diff options
Diffstat (limited to 'lib/CodeGen')
55 files changed, 9873 insertions, 4698 deletions
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h index df6dc7216a47e..468fe04399678 100644 --- a/lib/CodeGen/ABIInfo.h +++ b/lib/CodeGen/ABIInfo.h @@ -25,6 +25,7 @@ namespace clang {    class TargetInfo;    namespace CodeGen { +    class CGCXXABI;      class CGFunctionInfo;      class CodeGenFunction;      class CodeGenTypes; @@ -35,151 +36,6 @@ namespace clang {    // the targets to support this, since the Targets currently live in a    // layer below types n'stuff. -  /// ABIArgInfo - Helper class to encapsulate information about how a -  /// specific C type should be passed to or returned from a function. -  class ABIArgInfo { -  public: -    enum Kind { -      /// Direct - Pass the argument directly using the normal converted LLVM -      /// type, or by coercing to another specified type stored in -      /// 'CoerceToType').  If an offset is specified (in UIntData), then the -      /// argument passed is offset by some number of bytes in the memory -      /// representation. A dummy argument is emitted before the real argument -      /// if the specified type stored in "PaddingType" is not zero. -      Direct, - -      /// Extend - Valid only for integer argument types. Same as 'direct' -      /// but also emit a zero/sign extension attribute. -      Extend, - -      /// Indirect - Pass the argument indirectly via a hidden pointer -      /// with the specified alignment (0 indicates default alignment). -      Indirect, - -      /// Ignore - Ignore the argument (treat as void). Useful for void and -      /// empty structs. -      Ignore, - -      /// Expand - Only valid for aggregate argument types. The structure should -      /// be expanded into consecutive arguments for its constituent fields. -      /// Currently expand is only allowed on structures whose fields -      /// are all scalar types or are themselves expandable types. -      Expand, - -      KindFirst=Direct, KindLast=Expand -    }; - -  private: -    Kind TheKind; -    llvm::Type *TypeData; -    llvm::Type *PaddingType; -    unsigned UIntData; -    bool BoolData0; -    bool BoolData1; -    bool InReg; -    bool PaddingInReg; - -    ABIArgInfo(Kind K, llvm::Type *TD, unsigned UI, bool B0, bool B1, bool IR, -               bool PIR, llvm::Type* P) -      : TheKind(K), TypeData(TD), PaddingType(P), UIntData(UI), BoolData0(B0), -        BoolData1(B1), InReg(IR), PaddingInReg(PIR) {} - -  public: -    ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {} - -    static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0, -                                llvm::Type *Padding = 0) { -      return ABIArgInfo(Direct, T, Offset, false, false, false, false, Padding); -    } -    static ABIArgInfo getDirectInReg(llvm::Type *T = 0) { -      return ABIArgInfo(Direct, T, 0, false, false, true, false, 0); -    } -    static ABIArgInfo getExtend(llvm::Type *T = 0) { -      return ABIArgInfo(Extend, T, 0, false, false, false, false, 0); -    } -    static ABIArgInfo getExtendInReg(llvm::Type *T = 0) { -      return ABIArgInfo(Extend, T, 0, false, false, true, false, 0); -    } -    static ABIArgInfo getIgnore() { -      return ABIArgInfo(Ignore, 0, 0, false, false, false, false, 0); -    } -    static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true -                                  , bool Realign = false -                                  , llvm::Type *Padding = 0) { -      return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, false, false,  -                        Padding); -    } -    static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true -                                  , bool Realign = false) { -      return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, true, false, 0); -    } -    static ABIArgInfo getExpand() { -      return ABIArgInfo(Expand, 0, 0, false, false, false, false, 0); -    } -    static ABIArgInfo getExpandWithPadding(bool PaddingInReg, -                                           llvm::Type *Padding) { -     return ABIArgInfo(Expand, 0, 0, false, false, false, PaddingInReg, -                       Padding); -    } - -    Kind getKind() const { return TheKind; } -    bool isDirect() const { return TheKind == Direct; } -    bool isExtend() const { return TheKind == Extend; } -    bool isIgnore() const { return TheKind == Ignore; } -    bool isIndirect() const { return TheKind == Indirect; } -    bool isExpand() const { return TheKind == Expand; } - -    bool canHaveCoerceToType() const { -      return TheKind == Direct || TheKind == Extend; -    } - -    // Direct/Extend accessors -    unsigned getDirectOffset() const { -      assert((isDirect() || isExtend()) && "Not a direct or extend kind"); -      return UIntData; -    } - -    llvm::Type *getPaddingType() const { -      return PaddingType; -    } - -    bool getPaddingInReg() const { -      return PaddingInReg; -    } - -    llvm::Type *getCoerceToType() const { -      assert(canHaveCoerceToType() && "Invalid kind!"); -      return TypeData; -    } - -    void setCoerceToType(llvm::Type *T) { -      assert(canHaveCoerceToType() && "Invalid kind!"); -      TypeData = T; -    } - -    bool getInReg() const { -      assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!"); -      return InReg; -    } - -    // Indirect accessors -    unsigned getIndirectAlign() const { -      assert(TheKind == Indirect && "Invalid kind!"); -      return UIntData; -    } - -    bool getIndirectByVal() const { -      assert(TheKind == Indirect && "Invalid kind!"); -      return BoolData0; -    } - -    bool getIndirectRealign() const { -      assert(TheKind == Indirect && "Invalid kind!"); -      return BoolData1; -    } - -    void dump() const; -  };    /// ABIInfo - Target specific hooks for defining how a type should be    /// passed or returned from functions. @@ -194,6 +50,7 @@ namespace clang {      virtual ~ABIInfo(); +    CodeGen::CGCXXABI &getCXXABI() const;      ASTContext &getContext() const;      llvm::LLVMContext &getVMContext() const;      const llvm::DataLayout &getDataLayout() const; diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index 45079c098984b..90b0f68bd6936 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -154,6 +154,14 @@ static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase      PM.add(createObjCARCOptPass());  } +static void addSampleProfileLoaderPass(const PassManagerBuilder &Builder, +                                       PassManagerBase &PM) { +  const PassManagerBuilderWrapper &BuilderWrapper = +      static_cast<const PassManagerBuilderWrapper &>(Builder); +  const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); +  PM.add(createSampleProfileLoaderPass(CGOpts.SampleProfileFile)); +} +  static void addBoundsCheckingPass(const PassManagerBuilder &Builder,                                      PassManagerBase &PM) {    PM.add(createBoundsCheckingPass()); @@ -206,6 +214,14 @@ static void addThreadSanitizerPass(const PassManagerBuilder &Builder,    PM.add(createThreadSanitizerPass(CGOpts.SanitizerBlacklistFile));  } +static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder, +                                     PassManagerBase &PM) { +  const PassManagerBuilderWrapper &BuilderWrapper = +      static_cast<const PassManagerBuilderWrapper&>(Builder); +  const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); +  PM.add(createDataFlowSanitizerPass(CGOpts.SanitizerBlacklistFile)); +} +  void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) {    unsigned OptLevel = CodeGenOpts.OptimizationLevel;    CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining(); @@ -220,10 +236,17 @@ void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) {    PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts);    PMBuilder.OptLevel = OptLevel;    PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; +  PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB; +  PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP; +  PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop; -  PMBuilder.DisableSimplifyLibCalls = !CodeGenOpts.SimplifyLibCalls;    PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;    PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; +  PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; + +  if (!CodeGenOpts.SampleProfileFile.empty()) +    PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, +                           addSampleProfileLoaderPass);    // In ObjC ARC mode, add the main ARC optimization passes.    if (LangOpts.ObjCAutoRefCount) { @@ -235,7 +258,7 @@ void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) {                             addObjCARCOptPass);    } -  if (LangOpts.Sanitize.Bounds) { +  if (LangOpts.Sanitize.LocalBounds) {      PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,                             addBoundsCheckingPass);      PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, @@ -263,6 +286,13 @@ void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) {                             addThreadSanitizerPass);    } +  if (LangOpts.Sanitize.DataFlow) { +    PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, +                           addDataFlowSanitizerPass); +    PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, +                           addDataFlowSanitizerPass); +  } +    // Figure out TargetLibraryInfo.    Triple TargetTriple(TheModule->getTargetTriple());    PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple); @@ -410,13 +440,10 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {    // Set frame pointer elimination mode.    if (!CodeGenOpts.DisableFPElim) {      Options.NoFramePointerElim = false; -    Options.NoFramePointerElimNonLeaf = false;    } else if (CodeGenOpts.OmitLeafFramePointer) {      Options.NoFramePointerElim = false; -    Options.NoFramePointerElimNonLeaf = true;    } else {      Options.NoFramePointerElim = true; -    Options.NoFramePointerElimNonLeaf = true;    }    if (CodeGenOpts.UseInitArray) @@ -452,11 +479,9 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {    Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath;    Options.UseSoftFloat = CodeGenOpts.SoftFloat;    Options.StackAlignmentOverride = CodeGenOpts.StackAlignment; -  Options.RealignStack = CodeGenOpts.StackRealignment;    Options.DisableTailCalls = CodeGenOpts.DisableTailCalls;    Options.TrapFuncName = CodeGenOpts.TrapFuncName;    Options.PositionIndependentExecutable = LangOpts.PIELevel != 0; -  Options.SSPBufferSize = CodeGenOpts.SSPBufferSize;    Options.EnableSegmentedStacks = CodeGenOpts.EnableSegmentedStacks;    TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU, @@ -529,6 +554,7 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) {                        Action != Backend_EmitLL);    TargetMachine *TM = CreateTargetMachine(UsesCodeGen);    if (UsesCodeGen && !TM) return; +  llvm::OwningPtr<TargetMachine> TMOwner(CodeGenOpts.DisableFree ? 0 : TM);    CreatePasses(TM);    switch (Action) { diff --git a/lib/CodeGen/CGAtomic.cpp b/lib/CodeGen/CGAtomic.cpp index 0b48a5c664357..0df2a4000e288 100644 --- a/lib/CodeGen/CGAtomic.cpp +++ b/lib/CodeGen/CGAtomic.cpp @@ -15,6 +15,8 @@  #include "CGCall.h"  #include "CodeGenModule.h"  #include "clang/AST/ASTContext.h" +#include "clang/CodeGen/CGFunctionInfo.h" +#include "llvm/ADT/StringExtras.h"  #include "llvm/IR/DataLayout.h"  #include "llvm/IR/Intrinsics.h"  #include "llvm/IR/Operator.h" @@ -92,7 +94,7 @@ namespace {        return (ValueSizeInBits != AtomicSizeInBits);      } -    void emitMemSetZeroIfNecessary(LValue dest) const; +    bool emitMemSetZeroIfNecessary(LValue dest) const;      llvm::Value *getAtomicSizeValue() const {        CharUnits size = CGF.getContext().toCharUnitsFromBits(AtomicSizeInBits); @@ -105,7 +107,8 @@ namespace {      /// Turn an atomic-layout object into an r-value.      RValue convertTempToRValue(llvm::Value *addr, -                               AggValueSlot resultSlot) const; +                               AggValueSlot resultSlot, +                               SourceLocation loc) const;      /// Copy an atomic r-value into atomic-layout memory.      void emitCopyIntoMemory(RValue rvalue, LValue lvalue) const; @@ -163,21 +166,22 @@ bool AtomicInfo::requiresMemSetZero(llvm::Type *type) const {      return !isFullSizeType(CGF.CGM, type->getStructElementType(0),                             AtomicSizeInBits / 2); -  // Just be pessimistic about aggregates. +  // Padding in structs has an undefined bit pattern.  User beware.    case TEK_Aggregate: -    return true; +    return false;    }    llvm_unreachable("bad evaluation kind");  } -void AtomicInfo::emitMemSetZeroIfNecessary(LValue dest) const { +bool AtomicInfo::emitMemSetZeroIfNecessary(LValue dest) const {    llvm::Value *addr = dest.getAddress();    if (!requiresMemSetZero(addr->getType()->getPointerElementType())) -    return; +    return false;    CGF.Builder.CreateMemSet(addr, llvm::ConstantInt::get(CGF.Int8Ty, 0),                             AtomicSizeInBits / 8,                             dest.getAlignment().getQuantity()); +  return true;  }  static void @@ -317,6 +321,22 @@ EmitValToTemp(CodeGenFunction &CGF, Expr *E) {    return DeclPtr;  } +static void +AddDirectArgument(CodeGenFunction &CGF, CallArgList &Args, +                  bool UseOptimizedLibcall, llvm::Value *Val, QualType ValTy, +                  SourceLocation Loc) { +  if (UseOptimizedLibcall) { +    // Load value and pass it to the function directly. +    unsigned Align = CGF.getContext().getTypeAlignInChars(ValTy).getQuantity(); +    Val = CGF.EmitLoadOfScalar(Val, false, Align, ValTy, Loc); +    Args.add(RValue::get(Val), ValTy); +  } else { +    // Non-optimized functions always take a reference. +    Args.add(RValue::get(CGF.EmitCastToVoidPtr(Val)), +                         CGF.getContext().VoidPtrTy); +  } +} +  RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {    QualType AtomicTy = E->getPtr()->getType()->getPointeeType();    QualType MemTy = AtomicTy; @@ -424,67 +444,142 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {    // Use a library call.  See: http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary .    if (UseLibcall) { +    bool UseOptimizedLibcall = false; +    switch (E->getOp()) { +    case AtomicExpr::AO__c11_atomic_fetch_add: +    case AtomicExpr::AO__atomic_fetch_add: +    case AtomicExpr::AO__c11_atomic_fetch_and: +    case AtomicExpr::AO__atomic_fetch_and: +    case AtomicExpr::AO__c11_atomic_fetch_or: +    case AtomicExpr::AO__atomic_fetch_or: +    case AtomicExpr::AO__c11_atomic_fetch_sub: +    case AtomicExpr::AO__atomic_fetch_sub: +    case AtomicExpr::AO__c11_atomic_fetch_xor: +    case AtomicExpr::AO__atomic_fetch_xor: +      // For these, only library calls for certain sizes exist. +      UseOptimizedLibcall = true; +      break; +    default: +      // Only use optimized library calls for sizes for which they exist. +      if (Size == 1 || Size == 2 || Size == 4 || Size == 8) +        UseOptimizedLibcall = true; +      break; +    } -    SmallVector<QualType, 5> Params;      CallArgList Args; -    // Size is always the first parameter -    Args.add(RValue::get(llvm::ConstantInt::get(SizeTy, Size)), -             getContext().getSizeType()); -    // Atomic address is always the second parameter -    Args.add(RValue::get(EmitCastToVoidPtr(Ptr)), -             getContext().VoidPtrTy); +    if (!UseOptimizedLibcall) { +      // For non-optimized library calls, the size is the first parameter +      Args.add(RValue::get(llvm::ConstantInt::get(SizeTy, Size)), +               getContext().getSizeType()); +    } +    // Atomic address is the first or second parameter +    Args.add(RValue::get(EmitCastToVoidPtr(Ptr)), getContext().VoidPtrTy); -    const char* LibCallName; -    QualType RetTy = getContext().VoidTy; +    std::string LibCallName; +    QualType RetTy; +    bool HaveRetTy = false;      switch (E->getOp()) {      // There is only one libcall for compare an exchange, because there is no      // optimisation benefit possible from a libcall version of a weak compare      // and exchange. -    // bool __atomic_compare_exchange(size_t size, void *obj, void *expected, +    // bool __atomic_compare_exchange(size_t size, void *mem, void *expected,      //                                void *desired, int success, int failure) +    // bool __atomic_compare_exchange_N(T *mem, T *expected, T desired, +    //                                  int success, int failure)      case AtomicExpr::AO__c11_atomic_compare_exchange_weak:      case AtomicExpr::AO__c11_atomic_compare_exchange_strong:      case AtomicExpr::AO__atomic_compare_exchange:      case AtomicExpr::AO__atomic_compare_exchange_n:        LibCallName = "__atomic_compare_exchange";        RetTy = getContext().BoolTy; -      Args.add(RValue::get(EmitCastToVoidPtr(Val1)), -               getContext().VoidPtrTy); -      Args.add(RValue::get(EmitCastToVoidPtr(Val2)), -               getContext().VoidPtrTy); -      Args.add(RValue::get(Order), -               getContext().IntTy); +      HaveRetTy = true; +      Args.add(RValue::get(EmitCastToVoidPtr(Val1)), getContext().VoidPtrTy); +      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val2, MemTy, +                        E->getExprLoc()); +      Args.add(RValue::get(Order), getContext().IntTy);        Order = OrderFail;        break;      // void __atomic_exchange(size_t size, void *mem, void *val, void *return,      //                        int order) +    // T __atomic_exchange_N(T *mem, T val, int order)      case AtomicExpr::AO__c11_atomic_exchange:      case AtomicExpr::AO__atomic_exchange_n:      case AtomicExpr::AO__atomic_exchange:        LibCallName = "__atomic_exchange"; -      Args.add(RValue::get(EmitCastToVoidPtr(Val1)), -               getContext().VoidPtrTy); -      Args.add(RValue::get(EmitCastToVoidPtr(Dest)), -               getContext().VoidPtrTy); +      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy, +                        E->getExprLoc());        break;      // void __atomic_store(size_t size, void *mem, void *val, int order) +    // void __atomic_store_N(T *mem, T val, int order)      case AtomicExpr::AO__c11_atomic_store:      case AtomicExpr::AO__atomic_store:      case AtomicExpr::AO__atomic_store_n:        LibCallName = "__atomic_store"; -      Args.add(RValue::get(EmitCastToVoidPtr(Val1)), -               getContext().VoidPtrTy); +      RetTy = getContext().VoidTy; +      HaveRetTy = true; +      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy, +                        E->getExprLoc());        break;      // void __atomic_load(size_t size, void *mem, void *return, int order) +    // T __atomic_load_N(T *mem, int order)      case AtomicExpr::AO__c11_atomic_load:      case AtomicExpr::AO__atomic_load:      case AtomicExpr::AO__atomic_load_n:        LibCallName = "__atomic_load"; -      Args.add(RValue::get(EmitCastToVoidPtr(Dest)), -               getContext().VoidPtrTy); +      break; +    // T __atomic_fetch_add_N(T *mem, T val, int order) +    case AtomicExpr::AO__c11_atomic_fetch_add: +    case AtomicExpr::AO__atomic_fetch_add: +      LibCallName = "__atomic_fetch_add"; +      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy, +                        E->getExprLoc()); +      break; +    // T __atomic_fetch_and_N(T *mem, T val, int order) +    case AtomicExpr::AO__c11_atomic_fetch_and: +    case AtomicExpr::AO__atomic_fetch_and: +      LibCallName = "__atomic_fetch_and"; +      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy, +                        E->getExprLoc()); +      break; +    // T __atomic_fetch_or_N(T *mem, T val, int order) +    case AtomicExpr::AO__c11_atomic_fetch_or: +    case AtomicExpr::AO__atomic_fetch_or: +      LibCallName = "__atomic_fetch_or"; +      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy, +                        E->getExprLoc()); +      break; +    // T __atomic_fetch_sub_N(T *mem, T val, int order) +    case AtomicExpr::AO__c11_atomic_fetch_sub: +    case AtomicExpr::AO__atomic_fetch_sub: +      LibCallName = "__atomic_fetch_sub"; +      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy, +                        E->getExprLoc()); +      break; +    // T __atomic_fetch_xor_N(T *mem, T val, int order) +    case AtomicExpr::AO__c11_atomic_fetch_xor: +    case AtomicExpr::AO__atomic_fetch_xor: +      LibCallName = "__atomic_fetch_xor"; +      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy, +                        E->getExprLoc());        break;      default: return EmitUnsupportedRValue(E, "atomic library call");      } + +    // Optimized functions have the size in their name. +    if (UseOptimizedLibcall) +      LibCallName += "_" + llvm::utostr(Size); +    // By default, assume we return a value of the atomic type. +    if (!HaveRetTy) { +      if (UseOptimizedLibcall) { +        // Value is returned directly. +        RetTy = MemTy; +      } else { +        // Value is returned through parameter before the order. +        RetTy = getContext().VoidTy; +        Args.add(RValue::get(EmitCastToVoidPtr(Dest)), +                 getContext().VoidPtrTy); +      } +    }      // order is always the last parameter      Args.add(RValue::get(Order),               getContext().IntTy); @@ -495,11 +590,11 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {      llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);      llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);      RValue Res = EmitCall(FuncInfo, Func, ReturnValueSlot(), Args); -    if (E->isCmpXChg()) +    if (!RetTy->isVoidType())        return Res;      if (E->getType()->isVoidType())        return RValue::get(0); -    return convertTempToRValue(Dest, E->getType()); +    return convertTempToRValue(Dest, E->getType(), E->getExprLoc());    }    bool IsStore = E->getOp() == AtomicExpr::AO__c11_atomic_store || @@ -554,7 +649,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {      }      if (E->getType()->isVoidType())        return RValue::get(0); -    return convertTempToRValue(OrigDest, E->getType()); +    return convertTempToRValue(OrigDest, E->getType(), E->getExprLoc());    }    // Long case, when Order isn't obviously constant. @@ -616,7 +711,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {    Builder.SetInsertPoint(ContBB);    if (E->getType()->isVoidType())      return RValue::get(0); -  return convertTempToRValue(OrigDest, E->getType()); +  return convertTempToRValue(OrigDest, E->getType(), E->getExprLoc());  }  llvm::Value *AtomicInfo::emitCastToAtomicIntPointer(llvm::Value *addr) const { @@ -628,48 +723,30 @@ llvm::Value *AtomicInfo::emitCastToAtomicIntPointer(llvm::Value *addr) const {  }  RValue AtomicInfo::convertTempToRValue(llvm::Value *addr, -                                       AggValueSlot resultSlot) const { -  if (EvaluationKind == TEK_Aggregate) { -    // Nothing to do if the result is ignored. -    if (resultSlot.isIgnored()) return resultSlot.asRValue(); - -    assert(resultSlot.getAddr() == addr || hasPadding()); - -    // In these cases, we should have emitted directly into the result slot. -    if (!hasPadding() || resultSlot.isValueOfAtomic()) -      return resultSlot.asRValue(); - -    // Otherwise, fall into the common path. -  } +                                       AggValueSlot resultSlot, +                                       SourceLocation loc) const { +  if (EvaluationKind == TEK_Aggregate) +    return resultSlot.asRValue();    // Drill into the padding structure if we have one.    if (hasPadding())      addr = CGF.Builder.CreateStructGEP(addr, 0); -  // If we're emitting to an aggregate, copy into the result slot. -  if (EvaluationKind == TEK_Aggregate) { -    CGF.EmitAggregateCopy(resultSlot.getAddr(), addr, getValueType(), -                          resultSlot.isVolatile()); -    return resultSlot.asRValue(); -  } -    // Otherwise, just convert the temporary to an r-value using the    // normal conversion routine. -  return CGF.convertTempToRValue(addr, getValueType()); +  return CGF.convertTempToRValue(addr, getValueType(), loc);  }  /// Emit a load from an l-value of atomic type.  Note that the r-value  /// we produce is an r-value of the atomic *value* type. -RValue CodeGenFunction::EmitAtomicLoad(LValue src, AggValueSlot resultSlot) { +RValue CodeGenFunction::EmitAtomicLoad(LValue src, SourceLocation loc, +                                       AggValueSlot resultSlot) {    AtomicInfo atomics(*this, src);    // Check whether we should use a library call.    if (atomics.shouldUseLibcall()) {      llvm::Value *tempAddr; -    if (resultSlot.isValueOfAtomic()) { -      assert(atomics.getEvaluationKind() == TEK_Aggregate); -      tempAddr = resultSlot.getPaddedAtomicAddr(); -    } else if (!resultSlot.isIgnored() && !atomics.hasPadding()) { +    if (!resultSlot.isIgnored()) {        assert(atomics.getEvaluationKind() == TEK_Aggregate);        tempAddr = resultSlot.getAddr();      } else { @@ -690,7 +767,7 @@ RValue CodeGenFunction::EmitAtomicLoad(LValue src, AggValueSlot resultSlot) {      emitAtomicLibcall(*this, "__atomic_load", getContext().VoidTy, args);      // Produce the r-value. -    return atomics.convertTempToRValue(tempAddr, resultSlot); +    return atomics.convertTempToRValue(tempAddr, resultSlot, loc);    }    // Okay, we're doing this natively. @@ -733,16 +810,10 @@ RValue CodeGenFunction::EmitAtomicLoad(LValue src, AggValueSlot resultSlot) {    llvm::Value *temp;    bool tempIsVolatile = false;    CharUnits tempAlignment; -  if (atomics.getEvaluationKind() == TEK_Aggregate && -      (!atomics.hasPadding() || resultSlot.isValueOfAtomic())) { +  if (atomics.getEvaluationKind() == TEK_Aggregate) {      assert(!resultSlot.isIgnored()); -    if (resultSlot.isValueOfAtomic()) { -      temp = resultSlot.getPaddedAtomicAddr(); -      tempAlignment = atomics.getAtomicAlignment(); -    } else { -      temp = resultSlot.getAddr(); -      tempAlignment = atomics.getValueAlignment(); -    } +    temp = resultSlot.getAddr(); +    tempAlignment = atomics.getValueAlignment();      tempIsVolatile = resultSlot.isVolatile();    } else {      temp = CreateMemTemp(atomics.getAtomicType(), "atomic-load-temp"); @@ -754,7 +825,7 @@ RValue CodeGenFunction::EmitAtomicLoad(LValue src, AggValueSlot resultSlot) {    Builder.CreateAlignedStore(result, castTemp, tempAlignment.getQuantity())      ->setVolatile(tempIsVolatile); -  return atomics.convertTempToRValue(temp, resultSlot); +  return atomics.convertTempToRValue(temp, resultSlot, loc);  } @@ -812,8 +883,7 @@ llvm::Value *AtomicInfo::materializeRValue(RValue rvalue) const {  /// Note that the r-value is expected to be an r-value *of the atomic  /// type*; this means that for aggregate r-values, it should include  /// storage for any padding that was necessary. -void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest, -                                      bool isInit) { +void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest, bool isInit) {    // If this is an aggregate r-value, it should agree in type except    // maybe for address-space qualification.    assert(!rvalue.isAggregate() || @@ -910,13 +980,11 @@ void CodeGenFunction::EmitAtomicInit(Expr *init, LValue dest) {    }    case TEK_Aggregate: { -    // Memset the buffer first if there's any possibility of -    // uninitialized internal bits. -    atomics.emitMemSetZeroIfNecessary(dest); - -    // HACK: whether the initializer actually has an atomic type -    // doesn't really seem reliable right now. +    // Fix up the destination if the initializer isn't an expression +    // of atomic type. +    bool Zeroed = false;      if (!init->getType()->isAtomicType()) { +      Zeroed = atomics.emitMemSetZeroIfNecessary(dest);        dest = atomics.projectValue(dest);      } @@ -924,7 +992,10 @@ void CodeGenFunction::EmitAtomicInit(Expr *init, LValue dest) {      AggValueSlot slot = AggValueSlot::forLValue(dest,                                          AggValueSlot::IsNotDestructed,                                          AggValueSlot::DoesNotNeedGCBarriers, -                                        AggValueSlot::IsNotAliased); +                                        AggValueSlot::IsNotAliased, +                                        Zeroed ? AggValueSlot::IsZeroed : +                                                 AggValueSlot::IsNotZeroed); +      EmitAggExpr(init, slot);      return;    } diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index ded019e64ae8e..692f9a0dd63f7 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -63,14 +63,16 @@ static llvm::Constant *buildDisposeHelper(CodeGenModule &CGM,  /// buildBlockDescriptor is accessed from 5th field of the Block_literal  /// meta-data and contains stationary information about the block literal.  /// Its definition will have 4 (or optinally 6) words. +/// \code  /// struct Block_descriptor {  ///   unsigned long reserved;  ///   unsigned long size;  // size of Block_literal metadata in bytes.  ///   void *copy_func_helper_decl;  // optional copy helper.  ///   void *destroy_func_decl; // optioanl destructor helper. -///   void *block_method_encoding_address;//@encode for block literal signature. +///   void *block_method_encoding_address; // @encode for block literal signature.  ///   void *block_layout_info; // encoding of captured block variables.  /// }; +/// \endcode  static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM,                                              const CGBlockInfo &blockInfo) {    ASTContext &C = CGM.getContext(); @@ -353,14 +355,9 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,    // First, 'this'.    if (block->capturesCXXThis()) { -    const DeclContext *DC = block->getDeclContext(); -    for (; isa<BlockDecl>(DC); DC = cast<BlockDecl>(DC)->getDeclContext()) -      ; -    QualType thisType; -    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) -      thisType = C.getPointerType(C.getRecordType(RD)); -    else -      thisType = cast<CXXMethodDecl>(DC)->getThisType(C); +    assert(CGF && CGF->CurFuncDecl && isa<CXXMethodDecl>(CGF->CurFuncDecl) && +           "Can't capture 'this' outside a method"); +    QualType thisType = cast<CXXMethodDecl>(CGF->CurFuncDecl)->getThisType(C);      llvm::Type *llvmType = CGM.getTypes().ConvertType(thisType);      std::pair<CharUnits,CharUnits> tinfo @@ -837,7 +834,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {                 type->isBlockPointerType()) {        // Load the block and do a simple retain.        LValue srcLV = MakeAddrLValue(src, type, align); -      llvm::Value *value = EmitLoadOfScalar(srcLV); +      llvm::Value *value = EmitLoadOfScalar(srcLV, SourceLocation());        value = EmitARCRetainNonBlock(value);        // Do a primitive store to the block field. @@ -934,7 +931,7 @@ llvm::Type *CodeGenModule::getGenericBlockLiteralType() {  } -RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E,  +RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,                                             ReturnValueSlot ReturnValue) {    const BlockPointerType *BPT =      E->getCallee()->getType()->getAs<BlockPointerType>(); @@ -1092,8 +1089,6 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,                                         bool IsLambdaConversionToBlock) {    const BlockDecl *blockDecl = blockInfo.getBlockDecl(); -  // Check if we should generate debug info for this block function. -  maybeInitializeDebugInfo();    CurGD = GD;    BlockInfo = &blockInfo; @@ -1167,9 +1162,8 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,      Alloca->setAlignment(Align);      // Set the DebugLocation to empty, so the store is recognized as a      // frame setup instruction by llvm::DwarfDebug::beginFunction(). -    Builder.DisableDebugLocations(); +    NoLocation NL(*this, Builder);      Builder.CreateAlignedStore(BlockPointer, Alloca, Align); -    Builder.EnableDebugLocations();      BlockPointerDbgLoc = Alloca;    } @@ -1307,9 +1301,6 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {    IdentifierInfo *II      = &CGM.getContext().Idents.get("__copy_helper_block_"); -  // Check if we should generate debug info for this block helper function. -  maybeInitializeDebugInfo(); -    FunctionDecl *FD = FunctionDecl::Create(C,                                            C.getTranslationUnitDecl(),                                            SourceLocation(), @@ -1317,7 +1308,10 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {                                            SC_Static,                                            false,                                            false); +  // Create a scope with an artificial location for the body of this function. +  ArtificialLocation AL(*this, Builder);    StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation()); +  AL.Emit();    llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo(); @@ -1479,9 +1473,6 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) {      llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,                             "__destroy_helper_block_", &CGM.getModule()); -  // Check if we should generate debug info for this block destroy function. -  maybeInitializeDebugInfo(); -    IdentifierInfo *II      = &CGM.getContext().Idents.get("__destroy_helper_block_"); @@ -1490,7 +1481,10 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) {                                            SourceLocation(), II, C.VoidTy, 0,                                            SC_Static,                                            false, false); +  // Create a scope with an artificial location for the body of this function. +  ArtificialLocation AL(*this, Builder);    StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation()); +  AL.Emit();    llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo(); @@ -1781,8 +1775,6 @@ generateByrefCopyHelper(CodeGenFunction &CGF,                                            SC_Static,                                            false, false); -  // Initialize debug info if necessary. -  CGF.maybeInitializeDebugInfo();    CGF.StartFunction(FD, R, Fn, FI, args, SourceLocation());    if (byrefInfo.needsCopy()) { @@ -1854,8 +1846,6 @@ generateByrefDisposeHelper(CodeGenFunction &CGF,                                            SourceLocation(), II, R, 0,                                            SC_Static,                                            false, false); -  // Initialize debug info if necessary. -  CGF.maybeInitializeDebugInfo();    CGF.StartFunction(FD, R, Fn, FI, args, SourceLocation());    if (byrefInfo.needsDispose()) { diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index d18767897f39a..7726ad309d8af 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -19,6 +19,7 @@  #include "clang/AST/Decl.h"  #include "clang/Basic/TargetBuiltins.h"  #include "clang/Basic/TargetInfo.h" +#include "clang/CodeGen/CGFunctionInfo.h"  #include "llvm/IR/DataLayout.h"  #include "llvm/IR/Intrinsics.h" @@ -165,7 +166,7 @@ static Value *EmitFAbs(CodeGenFunction &CGF, Value *V, QualType ValTy) {  static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *Fn,                                const CallExpr *E, llvm::Value *calleeValue) { -  return CGF.EmitCall(E->getCallee()->getType(), calleeValue, +  return CGF.EmitCall(E->getCallee()->getType(), calleeValue, E->getLocStart(),                        ReturnValueSlot(), E->arg_begin(), E->arg_end(), Fn);  } @@ -408,8 +409,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,      assert(CI);      uint64_t val = CI->getZExtValue();      CI = ConstantInt::get(Builder.getInt1Ty(), (val & 0x2) >> 1); - -    Value *F = CGM.getIntrinsic(Intrinsic::objectsize, ResType); +    // FIXME: Get right address space. +    llvm::Type *Tys[] = { ResType, Builder.getInt8PtrTy(0) }; +    Value *F = CGM.getIntrinsic(Intrinsic::objectsize, Tys);      return RValue::get(Builder.CreateCall2(F, EmitScalarExpr(E->getArg(0)),CI));    }    case Builtin::BI__builtin_prefetch: { @@ -602,6 +604,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,    }    case Builtin::BIalloca: +  case Builtin::BI_alloca:    case Builtin::BI__builtin_alloca: {      Value *Size = EmitScalarExpr(E->getArg(0));      return RValue::get(Builder.CreateAlloca(Builder.getInt8Ty(), Size)); @@ -1282,18 +1285,25 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,    case Builtin::BIsqrt:    case Builtin::BIsqrtf:    case Builtin::BIsqrtl: { -    // TODO: there is currently no set of optimizer flags -    // sufficient for us to rewrite sqrt to @llvm.sqrt. -    // -fmath-errno=0 is not good enough; we need finiteness. -    // We could probably precondition the call with an ult -    // against 0, but is that worth the complexity? -    break; +    // Transform a call to sqrt* into a @llvm.sqrt.* intrinsic call, but only +    // in finite- or unsafe-math mode (the intrinsic has different semantics +    // for handling negative numbers compared to the library function, so +    // -fmath-errno=0 is not enough). +    if (!FD->hasAttr<ConstAttr>()) +      break; +    if (!(CGM.getCodeGenOpts().UnsafeFPMath || +          CGM.getCodeGenOpts().NoNaNsFPMath)) +      break; +    Value *Arg0 = EmitScalarExpr(E->getArg(0)); +    llvm::Type *ArgType = Arg0->getType(); +    Value *F = CGM.getIntrinsic(Intrinsic::sqrt, ArgType); +    return RValue::get(Builder.CreateCall(F, Arg0));    }    case Builtin::BIpow:    case Builtin::BIpowf:    case Builtin::BIpowl: { -    // Rewrite sqrt to intrinsic if allowed. +    // Transform a call to pow* into a @llvm.pow.* intrinsic call.      if (!FD->hasAttr<ConstAttr>())        break;      Value *Base = EmitScalarExpr(E->getArg(0)); @@ -1301,6 +1311,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,      llvm::Type *ArgType = Base->getType();      Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType);      return RValue::get(Builder.CreateCall2(F, Base, Exponent)); +    break;    }    case Builtin::BIfma: @@ -1345,10 +1356,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,      StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString();      return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc()));    } +  case Builtin::BI__builtin_addcb:    case Builtin::BI__builtin_addcs:    case Builtin::BI__builtin_addc:    case Builtin::BI__builtin_addcl:    case Builtin::BI__builtin_addcll: +  case Builtin::BI__builtin_subcb:    case Builtin::BI__builtin_subcs:    case Builtin::BI__builtin_subc:    case Builtin::BI__builtin_subcl: @@ -1382,12 +1395,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,      llvm::Intrinsic::ID IntrinsicId;      switch (BuiltinID) {      default: llvm_unreachable("Unknown multiprecision builtin id."); +    case Builtin::BI__builtin_addcb:      case Builtin::BI__builtin_addcs:      case Builtin::BI__builtin_addc:      case Builtin::BI__builtin_addcl:      case Builtin::BI__builtin_addcll:        IntrinsicId = llvm::Intrinsic::uadd_with_overflow;        break; +    case Builtin::BI__builtin_subcb:      case Builtin::BI__builtin_subcs:      case Builtin::BI__builtin_subc:      case Builtin::BI__builtin_subcl: @@ -1410,6 +1425,79 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,      CarryOutStore->setAlignment(CarryOutPtr.second);      return RValue::get(Sum2);    } +  case Builtin::BI__builtin_uadd_overflow: +  case Builtin::BI__builtin_uaddl_overflow: +  case Builtin::BI__builtin_uaddll_overflow: +  case Builtin::BI__builtin_usub_overflow: +  case Builtin::BI__builtin_usubl_overflow: +  case Builtin::BI__builtin_usubll_overflow: +  case Builtin::BI__builtin_umul_overflow: +  case Builtin::BI__builtin_umull_overflow: +  case Builtin::BI__builtin_umulll_overflow: +  case Builtin::BI__builtin_sadd_overflow: +  case Builtin::BI__builtin_saddl_overflow: +  case Builtin::BI__builtin_saddll_overflow: +  case Builtin::BI__builtin_ssub_overflow: +  case Builtin::BI__builtin_ssubl_overflow: +  case Builtin::BI__builtin_ssubll_overflow: +  case Builtin::BI__builtin_smul_overflow: +  case Builtin::BI__builtin_smull_overflow: +  case Builtin::BI__builtin_smulll_overflow: { + +    // We translate all of these builtins directly to the relevant llvm IR node. + +    // Scalarize our inputs. +    llvm::Value *X = EmitScalarExpr(E->getArg(0)); +    llvm::Value *Y = EmitScalarExpr(E->getArg(1)); +    std::pair<llvm::Value *, unsigned> SumOutPtr = +      EmitPointerWithAlignment(E->getArg(2)); + +    // Decide which of the overflow intrinsics we are lowering to: +    llvm::Intrinsic::ID IntrinsicId; +    switch (BuiltinID) { +    default: llvm_unreachable("Unknown security overflow builtin id."); +    case Builtin::BI__builtin_uadd_overflow: +    case Builtin::BI__builtin_uaddl_overflow: +    case Builtin::BI__builtin_uaddll_overflow: +      IntrinsicId = llvm::Intrinsic::uadd_with_overflow; +      break; +    case Builtin::BI__builtin_usub_overflow: +    case Builtin::BI__builtin_usubl_overflow: +    case Builtin::BI__builtin_usubll_overflow: +      IntrinsicId = llvm::Intrinsic::usub_with_overflow; +      break; +    case Builtin::BI__builtin_umul_overflow: +    case Builtin::BI__builtin_umull_overflow: +    case Builtin::BI__builtin_umulll_overflow: +      IntrinsicId = llvm::Intrinsic::umul_with_overflow; +      break; +    case Builtin::BI__builtin_sadd_overflow: +    case Builtin::BI__builtin_saddl_overflow: +    case Builtin::BI__builtin_saddll_overflow: +      IntrinsicId = llvm::Intrinsic::sadd_with_overflow; +      break; +    case Builtin::BI__builtin_ssub_overflow: +    case Builtin::BI__builtin_ssubl_overflow: +    case Builtin::BI__builtin_ssubll_overflow: +      IntrinsicId = llvm::Intrinsic::ssub_with_overflow; +      break; +    case Builtin::BI__builtin_smul_overflow: +    case Builtin::BI__builtin_smull_overflow: +    case Builtin::BI__builtin_smulll_overflow: +      IntrinsicId = llvm::Intrinsic::smul_with_overflow; +      break; +    } + +     +    llvm::Value *Carry; +    llvm::Value *Sum = EmitOverflowIntrinsic(*this, IntrinsicId, X, Y, Carry); +    llvm::StoreInst *SumOutStore = Builder.CreateStore(Sum, SumOutPtr.first); +    SumOutStore->setAlignment(SumOutPtr.second); + +    return RValue::get(Carry); +  } +  case Builtin::BI__builtin_addressof: +    return RValue::get(EmitLValue(E->getArg(0)).getAddress());    case Builtin::BI__noop:      return RValue::get(0);    } @@ -1512,6 +1600,7 @@ Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,      return EmitX86BuiltinExpr(BuiltinID, E);    case llvm::Triple::ppc:    case llvm::Triple::ppc64: +  case llvm::Triple::ppc64le:      return EmitPPCBuiltinExpr(BuiltinID, E);    default:      return 0; @@ -1519,24 +1608,28 @@ Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,  }  static llvm::VectorType *GetNeonType(CodeGenFunction *CGF, -                                     NeonTypeFlags TypeFlags) { +                                     NeonTypeFlags TypeFlags, +                                     bool V1Ty=false) {    int IsQuad = TypeFlags.isQuad();    switch (TypeFlags.getEltType()) {    case NeonTypeFlags::Int8:    case NeonTypeFlags::Poly8: -    return llvm::VectorType::get(CGF->Int8Ty, 8 << IsQuad); +    return llvm::VectorType::get(CGF->Int8Ty, V1Ty ? 1 : (8 << IsQuad));    case NeonTypeFlags::Int16:    case NeonTypeFlags::Poly16:    case NeonTypeFlags::Float16: -    return llvm::VectorType::get(CGF->Int16Ty, 4 << IsQuad); +    return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad));    case NeonTypeFlags::Int32: -    return llvm::VectorType::get(CGF->Int32Ty, 2 << IsQuad); +    return llvm::VectorType::get(CGF->Int32Ty, V1Ty ? 1 : (2 << IsQuad));    case NeonTypeFlags::Int64: -    return llvm::VectorType::get(CGF->Int64Ty, 1 << IsQuad); +  case NeonTypeFlags::Poly64: +    return llvm::VectorType::get(CGF->Int64Ty, V1Ty ? 1 : (1 << IsQuad));    case NeonTypeFlags::Float32: -    return llvm::VectorType::get(CGF->FloatTy, 2 << IsQuad); +    return llvm::VectorType::get(CGF->FloatTy, V1Ty ? 1 : (2 << IsQuad)); +  case NeonTypeFlags::Float64: +    return llvm::VectorType::get(CGF->DoubleTy, V1Ty ? 1 : (1 << IsQuad));    } -  llvm_unreachable("Invalid NeonTypeFlags element type!"); +  llvm_unreachable("Unknown vector element type!");  }  Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) { @@ -1568,6 +1661,39 @@ Value *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty,    return llvm::ConstantVector::getSplat(VTy->getNumElements(), C);  } +// \brief Right-shift a vector by a constant. +Value *CodeGenFunction::EmitNeonRShiftImm(Value *Vec, Value *Shift, +                                          llvm::Type *Ty, bool usgn, +                                          const char *name) { +  llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); + +  int ShiftAmt = cast<ConstantInt>(Shift)->getSExtValue(); +  int EltSize = VTy->getScalarSizeInBits(); + +  Vec = Builder.CreateBitCast(Vec, Ty); + +  // lshr/ashr are undefined when the shift amount is equal to the vector +  // element size. +  if (ShiftAmt == EltSize) { +    if (usgn) { +      // Right-shifting an unsigned value by its size yields 0. +      llvm::Constant *Zero = ConstantInt::get(VTy->getElementType(), 0); +      return llvm::ConstantVector::getSplat(VTy->getNumElements(), Zero); +    } else { +      // Right-shifting a signed value by its size is equivalent +      // to a shift of size-1. +      --ShiftAmt; +      Shift = ConstantInt::get(VTy->getElementType(), ShiftAmt); +    } +  } + +  Shift = EmitNeonShiftVector(Shift, Ty, false); +  if (usgn) +    return Builder.CreateLShr(Vec, Shift, name); +  else +    return Builder.CreateAShr(Vec, Shift, name); +} +  /// GetPointeeAlignment - Given an expression with a pointer type, find the  /// alignment of the type referenced by the pointer.  Skip over implicit  /// casts. @@ -1623,8 +1749,1140 @@ CodeGenFunction::EmitPointerWithAlignment(const Expr *Addr) {    return std::make_pair(EmitScalarExpr(Addr), Align);  } +static Value *EmitAArch64ScalarBuiltinExpr(CodeGenFunction &CGF, +                                           unsigned BuiltinID, +                                           const CallExpr *E) { +  unsigned int Int = 0; +  // Scalar result generated across vectors +  bool AcrossVec = false; +  // Extend element of one-element vector +  bool ExtendEle = false; +  bool OverloadInt = false; +  bool OverloadCmpInt = false; +  bool IsFpCmpZInt = false; +  bool OverloadCvtInt = false; +  bool OverloadWideInt = false; +  bool OverloadNarrowInt = false; +  const char *s = NULL; + +  SmallVector<Value *, 4> Ops; +  for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { +    Ops.push_back(CGF.EmitScalarExpr(E->getArg(i))); +  } + +  // AArch64 scalar builtins are not overloaded, they do not have an extra +  // argument that specifies the vector type, need to handle each case. +  switch (BuiltinID) { +  default: break; +  case AArch64::BI__builtin_neon_vdups_lane_f32: +  case AArch64::BI__builtin_neon_vdupd_lane_f64: +  case AArch64::BI__builtin_neon_vdups_laneq_f32: +  case AArch64::BI__builtin_neon_vdupd_laneq_f64: { +    return CGF.Builder.CreateExtractElement(Ops[0], Ops[1], "vdup_lane"); +  } +  case AArch64::BI__builtin_neon_vdupb_lane_i8: +  case AArch64::BI__builtin_neon_vduph_lane_i16: +  case AArch64::BI__builtin_neon_vdups_lane_i32: +  case AArch64::BI__builtin_neon_vdupd_lane_i64: +  case AArch64::BI__builtin_neon_vdupb_laneq_i8: +  case AArch64::BI__builtin_neon_vduph_laneq_i16: +  case AArch64::BI__builtin_neon_vdups_laneq_i32: +  case AArch64::BI__builtin_neon_vdupd_laneq_i64: { +    // The backend treats Neon scalar types as v1ix types +    // So we want to dup lane from any vector to v1ix vector +    // with shufflevector +    s = "vdup_lane"; +    Value* SV = llvm::ConstantVector::getSplat(1, cast<ConstantInt>(Ops[1])); +    Value *Result = CGF.Builder.CreateShuffleVector(Ops[0], Ops[0], SV, s); +    llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType()); +    // AArch64 intrinsic one-element vector type cast to +    // scalar type expected by the builtin +    return CGF.Builder.CreateBitCast(Result, Ty, s); +  } +  case AArch64::BI__builtin_neon_vqdmlalh_lane_s16 : +  case AArch64::BI__builtin_neon_vqdmlalh_laneq_s16 : +  case AArch64::BI__builtin_neon_vqdmlals_lane_s32 : +  case AArch64::BI__builtin_neon_vqdmlals_laneq_s32 : +  case AArch64::BI__builtin_neon_vqdmlslh_lane_s16 : +  case AArch64::BI__builtin_neon_vqdmlslh_laneq_s16 : +  case AArch64::BI__builtin_neon_vqdmlsls_lane_s32 : +  case AArch64::BI__builtin_neon_vqdmlsls_laneq_s32 : { +    Int = Intrinsic::arm_neon_vqadds; +    if (BuiltinID == AArch64::BI__builtin_neon_vqdmlslh_lane_s16 || +        BuiltinID == AArch64::BI__builtin_neon_vqdmlslh_laneq_s16 || +        BuiltinID == AArch64::BI__builtin_neon_vqdmlsls_lane_s32 || +        BuiltinID == AArch64::BI__builtin_neon_vqdmlsls_laneq_s32) { +      Int = Intrinsic::arm_neon_vqsubs; +    } +    // create vqdmull call with b * c[i] +    llvm::Type *Ty = CGF.ConvertType(E->getArg(1)->getType()); +    llvm::VectorType *OpVTy = llvm::VectorType::get(Ty, 1); +    Ty = CGF.ConvertType(E->getArg(0)->getType()); +    llvm::VectorType *ResVTy = llvm::VectorType::get(Ty, 1); +    Value *F = CGF.CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, ResVTy); +    Value *V = UndefValue::get(OpVTy); +    llvm::Constant *CI = ConstantInt::get(CGF.Int32Ty, 0); +    SmallVector<Value *, 2> MulOps; +    MulOps.push_back(Ops[1]); +    MulOps.push_back(Ops[2]); +    MulOps[0] = CGF.Builder.CreateInsertElement(V, MulOps[0], CI); +    MulOps[1] = CGF.Builder.CreateExtractElement(MulOps[1], Ops[3], "extract"); +    MulOps[1] = CGF.Builder.CreateInsertElement(V, MulOps[1], CI); +    Value *MulRes = CGF.Builder.CreateCall2(F, MulOps[0], MulOps[1]); +    // create vqadds call with a +/- vqdmull result +    F = CGF.CGM.getIntrinsic(Int, ResVTy); +    SmallVector<Value *, 2> AddOps; +    AddOps.push_back(Ops[0]); +    AddOps.push_back(MulRes); +    V = UndefValue::get(ResVTy); +    AddOps[0] = CGF.Builder.CreateInsertElement(V, AddOps[0], CI); +    Value *AddRes = CGF.Builder.CreateCall2(F, AddOps[0], AddOps[1]); +    return CGF.Builder.CreateBitCast(AddRes, Ty); +  } +  case AArch64::BI__builtin_neon_vfmas_lane_f32: +  case AArch64::BI__builtin_neon_vfmas_laneq_f32: +  case AArch64::BI__builtin_neon_vfmad_lane_f64: +  case AArch64::BI__builtin_neon_vfmad_laneq_f64: { +    llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType()); +    Value *F = CGF.CGM.getIntrinsic(Intrinsic::fma, Ty); +    Ops[2] = CGF.Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); +    return CGF.Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); +  } +  // Scalar Floating-point Multiply Extended +  case AArch64::BI__builtin_neon_vmulxs_f32: +  case AArch64::BI__builtin_neon_vmulxd_f64: { +    Int = Intrinsic::aarch64_neon_vmulx; +    llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType()); +    return CGF.EmitNeonCall(CGF.CGM.getIntrinsic(Int, Ty), Ops, "vmulx"); +  } +  case AArch64::BI__builtin_neon_vmul_n_f64: { +    // v1f64 vmul_n_f64  should be mapped to Neon scalar mul lane +    llvm::Type *VTy = GetNeonType(&CGF, +      NeonTypeFlags(NeonTypeFlags::Float64, false, false)); +    Ops[0] = CGF.Builder.CreateBitCast(Ops[0], VTy); +    llvm::Value *Idx = llvm::ConstantInt::get(CGF.Int32Ty, 0); +    Ops[0] = CGF.Builder.CreateExtractElement(Ops[0], Idx, "extract"); +    Value *Result = CGF.Builder.CreateFMul(Ops[0], Ops[1]); +    return CGF.Builder.CreateBitCast(Result, VTy); +  } +  case AArch64::BI__builtin_neon_vget_lane_i8: +  case AArch64::BI__builtin_neon_vget_lane_i16: +  case AArch64::BI__builtin_neon_vget_lane_i32: +  case AArch64::BI__builtin_neon_vget_lane_i64: +  case AArch64::BI__builtin_neon_vget_lane_f32: +  case AArch64::BI__builtin_neon_vget_lane_f64: +  case AArch64::BI__builtin_neon_vgetq_lane_i8: +  case AArch64::BI__builtin_neon_vgetq_lane_i16: +  case AArch64::BI__builtin_neon_vgetq_lane_i32: +  case AArch64::BI__builtin_neon_vgetq_lane_i64: +  case AArch64::BI__builtin_neon_vgetq_lane_f32: +  case AArch64::BI__builtin_neon_vgetq_lane_f64: +    return CGF.EmitARMBuiltinExpr(ARM::BI__builtin_neon_vget_lane_i8, E); +  case AArch64::BI__builtin_neon_vset_lane_i8: +  case AArch64::BI__builtin_neon_vset_lane_i16: +  case AArch64::BI__builtin_neon_vset_lane_i32: +  case AArch64::BI__builtin_neon_vset_lane_i64: +  case AArch64::BI__builtin_neon_vset_lane_f32: +  case AArch64::BI__builtin_neon_vset_lane_f64: +  case AArch64::BI__builtin_neon_vsetq_lane_i8: +  case AArch64::BI__builtin_neon_vsetq_lane_i16: +  case AArch64::BI__builtin_neon_vsetq_lane_i32: +  case AArch64::BI__builtin_neon_vsetq_lane_i64: +  case AArch64::BI__builtin_neon_vsetq_lane_f32: +  case AArch64::BI__builtin_neon_vsetq_lane_f64: +    return CGF.EmitARMBuiltinExpr(ARM::BI__builtin_neon_vset_lane_i8, E); +  // Crypto +  case AArch64::BI__builtin_neon_vsha1h_u32: +    Int = Intrinsic::arm_neon_sha1h; +    s = "sha1h"; OverloadInt = true; break; +  case AArch64::BI__builtin_neon_vsha1cq_u32: +    Int = Intrinsic::aarch64_neon_sha1c; +    s = "sha1c"; break; +  case AArch64::BI__builtin_neon_vsha1pq_u32: +    Int = Intrinsic::aarch64_neon_sha1p; +    s = "sha1p"; break; +  case AArch64::BI__builtin_neon_vsha1mq_u32: +    Int = Intrinsic::aarch64_neon_sha1m; +    s = "sha1m"; break; +  // Scalar Add +  case AArch64::BI__builtin_neon_vaddd_s64: +    Int = Intrinsic::aarch64_neon_vaddds; +    s = "vaddds"; break; +  case AArch64::BI__builtin_neon_vaddd_u64: +    Int = Intrinsic::aarch64_neon_vadddu; +    s = "vadddu"; break; +  // Scalar Sub +  case AArch64::BI__builtin_neon_vsubd_s64: +    Int = Intrinsic::aarch64_neon_vsubds; +    s = "vsubds"; break; +  case AArch64::BI__builtin_neon_vsubd_u64: +    Int = Intrinsic::aarch64_neon_vsubdu; +    s = "vsubdu"; break; +  // Scalar Saturating Add +  case AArch64::BI__builtin_neon_vqaddb_s8: +  case AArch64::BI__builtin_neon_vqaddh_s16: +  case AArch64::BI__builtin_neon_vqadds_s32: +  case AArch64::BI__builtin_neon_vqaddd_s64: +    Int = Intrinsic::arm_neon_vqadds; +    s = "vqadds"; OverloadInt = true; break; +  case AArch64::BI__builtin_neon_vqaddb_u8: +  case AArch64::BI__builtin_neon_vqaddh_u16: +  case AArch64::BI__builtin_neon_vqadds_u32: +  case AArch64::BI__builtin_neon_vqaddd_u64: +    Int = Intrinsic::arm_neon_vqaddu; +    s = "vqaddu"; OverloadInt = true; break; +  // Scalar Saturating Sub +  case AArch64::BI__builtin_neon_vqsubb_s8: +  case AArch64::BI__builtin_neon_vqsubh_s16: +  case AArch64::BI__builtin_neon_vqsubs_s32: +  case AArch64::BI__builtin_neon_vqsubd_s64: +    Int = Intrinsic::arm_neon_vqsubs; +    s = "vqsubs"; OverloadInt = true; break; +  case AArch64::BI__builtin_neon_vqsubb_u8: +  case AArch64::BI__builtin_neon_vqsubh_u16: +  case AArch64::BI__builtin_neon_vqsubs_u32: +  case AArch64::BI__builtin_neon_vqsubd_u64: +    Int = Intrinsic::arm_neon_vqsubu; +    s = "vqsubu"; OverloadInt = true; break; +  // Scalar Shift Left +  case AArch64::BI__builtin_neon_vshld_s64: +    Int = Intrinsic::aarch64_neon_vshlds; +    s = "vshlds"; break; +  case AArch64::BI__builtin_neon_vshld_u64: +    Int = Intrinsic::aarch64_neon_vshldu; +    s = "vshldu"; break; +  // Scalar Saturating Shift Left +  case AArch64::BI__builtin_neon_vqshlb_s8: +  case AArch64::BI__builtin_neon_vqshlh_s16: +  case AArch64::BI__builtin_neon_vqshls_s32: +  case AArch64::BI__builtin_neon_vqshld_s64: +    Int = Intrinsic::aarch64_neon_vqshls; +    s = "vqshls"; OverloadInt = true; break; +  case AArch64::BI__builtin_neon_vqshlb_u8: +  case AArch64::BI__builtin_neon_vqshlh_u16: +  case AArch64::BI__builtin_neon_vqshls_u32: +  case AArch64::BI__builtin_neon_vqshld_u64: +    Int = Intrinsic::aarch64_neon_vqshlu; +    s = "vqshlu"; OverloadInt = true; break; +  // Scalar Rouding Shift Left +  case AArch64::BI__builtin_neon_vrshld_s64: +    Int = Intrinsic::aarch64_neon_vrshlds; +    s = "vrshlds"; break; +  case AArch64::BI__builtin_neon_vrshld_u64: +    Int = Intrinsic::aarch64_neon_vrshldu; +    s = "vrshldu"; break; +  // Scalar Saturating Rouding Shift Left +  case AArch64::BI__builtin_neon_vqrshlb_s8: +  case AArch64::BI__builtin_neon_vqrshlh_s16: +  case AArch64::BI__builtin_neon_vqrshls_s32: +  case AArch64::BI__builtin_neon_vqrshld_s64: +    Int = Intrinsic::aarch64_neon_vqrshls; +    s = "vqrshls"; OverloadInt = true; break; +  case AArch64::BI__builtin_neon_vqrshlb_u8: +  case AArch64::BI__builtin_neon_vqrshlh_u16: +  case AArch64::BI__builtin_neon_vqrshls_u32: +  case AArch64::BI__builtin_neon_vqrshld_u64: +    Int = Intrinsic::aarch64_neon_vqrshlu; +    s = "vqrshlu"; OverloadInt = true; break; +  // Scalar Reduce Pairwise Add +  case AArch64::BI__builtin_neon_vpaddd_s64: +  case AArch64::BI__builtin_neon_vpaddd_u64: +    Int = Intrinsic::aarch64_neon_vpadd; s = "vpadd"; +    break; +  case AArch64::BI__builtin_neon_vpadds_f32: +    Int = Intrinsic::aarch64_neon_vpfadd; s = "vpfadd"; +    break; +  case AArch64::BI__builtin_neon_vpaddd_f64: +    Int = Intrinsic::aarch64_neon_vpfaddq; s = "vpfaddq"; +    break; +  // Scalar Reduce Pairwise Floating Point Max +  case AArch64::BI__builtin_neon_vpmaxs_f32: +    Int = Intrinsic::aarch64_neon_vpmax; s = "vpmax"; +    break; +  case AArch64::BI__builtin_neon_vpmaxqd_f64: +    Int = Intrinsic::aarch64_neon_vpmaxq; s = "vpmaxq"; +    break; +  // Scalar Reduce Pairwise Floating Point Min +  case AArch64::BI__builtin_neon_vpmins_f32: +    Int = Intrinsic::aarch64_neon_vpmin; s = "vpmin"; +    break; +  case AArch64::BI__builtin_neon_vpminqd_f64: +    Int = Intrinsic::aarch64_neon_vpminq; s = "vpminq"; +    break; +  // Scalar Reduce Pairwise Floating Point Maxnm +  case AArch64::BI__builtin_neon_vpmaxnms_f32: +    Int = Intrinsic::aarch64_neon_vpfmaxnm; s = "vpfmaxnm"; +    break; +  case AArch64::BI__builtin_neon_vpmaxnmqd_f64: +    Int = Intrinsic::aarch64_neon_vpfmaxnmq; s = "vpfmaxnmq"; +    break; +  // Scalar Reduce Pairwise Floating Point Minnm +  case AArch64::BI__builtin_neon_vpminnms_f32: +    Int = Intrinsic::aarch64_neon_vpfminnm; s = "vpfminnm"; +    break; +  case AArch64::BI__builtin_neon_vpminnmqd_f64: +    Int = Intrinsic::aarch64_neon_vpfminnmq; s = "vpfminnmq"; +    break; +  // The followings are intrinsics with scalar results generated AcrossVec vectors +  case AArch64::BI__builtin_neon_vaddlv_s8: +  case AArch64::BI__builtin_neon_vaddlv_s16: +  case AArch64::BI__builtin_neon_vaddlvq_s8: +  case AArch64::BI__builtin_neon_vaddlvq_s16: +  case AArch64::BI__builtin_neon_vaddlvq_s32: +    Int = Intrinsic::aarch64_neon_saddlv; +    AcrossVec = true; ExtendEle = true; s = "saddlv"; break; +  case AArch64::BI__builtin_neon_vaddlv_u8: +  case AArch64::BI__builtin_neon_vaddlv_u16: +  case AArch64::BI__builtin_neon_vaddlvq_u8: +  case AArch64::BI__builtin_neon_vaddlvq_u16: +  case AArch64::BI__builtin_neon_vaddlvq_u32: +    Int = Intrinsic::aarch64_neon_uaddlv; +    AcrossVec = true; ExtendEle = true; s = "uaddlv"; break; +  case AArch64::BI__builtin_neon_vmaxv_s8: +  case AArch64::BI__builtin_neon_vmaxv_s16: +  case AArch64::BI__builtin_neon_vmaxvq_s8: +  case AArch64::BI__builtin_neon_vmaxvq_s16: +  case AArch64::BI__builtin_neon_vmaxvq_s32: +    Int = Intrinsic::aarch64_neon_smaxv; +    AcrossVec = true; ExtendEle = false; s = "smaxv"; break; +  case AArch64::BI__builtin_neon_vmaxv_u8: +  case AArch64::BI__builtin_neon_vmaxv_u16: +  case AArch64::BI__builtin_neon_vmaxvq_u8: +  case AArch64::BI__builtin_neon_vmaxvq_u16: +  case AArch64::BI__builtin_neon_vmaxvq_u32: +    Int = Intrinsic::aarch64_neon_umaxv; +    AcrossVec = true; ExtendEle = false; s = "umaxv"; break; +  case AArch64::BI__builtin_neon_vminv_s8: +  case AArch64::BI__builtin_neon_vminv_s16: +  case AArch64::BI__builtin_neon_vminvq_s8: +  case AArch64::BI__builtin_neon_vminvq_s16: +  case AArch64::BI__builtin_neon_vminvq_s32: +    Int = Intrinsic::aarch64_neon_sminv; +    AcrossVec = true; ExtendEle = false; s = "sminv"; break; +  case AArch64::BI__builtin_neon_vminv_u8: +  case AArch64::BI__builtin_neon_vminv_u16: +  case AArch64::BI__builtin_neon_vminvq_u8: +  case AArch64::BI__builtin_neon_vminvq_u16: +  case AArch64::BI__builtin_neon_vminvq_u32: +    Int = Intrinsic::aarch64_neon_uminv; +    AcrossVec = true; ExtendEle = false; s = "uminv"; break; +  case AArch64::BI__builtin_neon_vaddv_s8: +  case AArch64::BI__builtin_neon_vaddv_s16: +  case AArch64::BI__builtin_neon_vaddvq_s8: +  case AArch64::BI__builtin_neon_vaddvq_s16: +  case AArch64::BI__builtin_neon_vaddvq_s32: +  case AArch64::BI__builtin_neon_vaddvq_s64: +  case AArch64::BI__builtin_neon_vaddv_u8: +  case AArch64::BI__builtin_neon_vaddv_u16: +  case AArch64::BI__builtin_neon_vaddvq_u8: +  case AArch64::BI__builtin_neon_vaddvq_u16: +  case AArch64::BI__builtin_neon_vaddvq_u32: +  case AArch64::BI__builtin_neon_vaddvq_u64: +  case AArch64::BI__builtin_neon_vaddv_f32: +  case AArch64::BI__builtin_neon_vaddvq_f32: +  case AArch64::BI__builtin_neon_vaddvq_f64: +    Int = Intrinsic::aarch64_neon_vaddv; +    AcrossVec = true; ExtendEle = false; s = "vaddv"; break;       +  case AArch64::BI__builtin_neon_vmaxv_f32: +  case AArch64::BI__builtin_neon_vmaxvq_f32: +  case AArch64::BI__builtin_neon_vmaxvq_f64: +    Int = Intrinsic::aarch64_neon_vmaxv; +    AcrossVec = true; ExtendEle = false; s = "vmaxv"; break; +  case AArch64::BI__builtin_neon_vminv_f32: +  case AArch64::BI__builtin_neon_vminvq_f32: +  case AArch64::BI__builtin_neon_vminvq_f64: +    Int = Intrinsic::aarch64_neon_vminv; +    AcrossVec = true; ExtendEle = false; s = "vminv"; break; +  case AArch64::BI__builtin_neon_vmaxnmv_f32: +  case AArch64::BI__builtin_neon_vmaxnmvq_f32: +  case AArch64::BI__builtin_neon_vmaxnmvq_f64: +    Int = Intrinsic::aarch64_neon_vmaxnmv; +    AcrossVec = true; ExtendEle = false; s = "vmaxnmv"; break; +  case AArch64::BI__builtin_neon_vminnmv_f32: +  case AArch64::BI__builtin_neon_vminnmvq_f32: +  case AArch64::BI__builtin_neon_vminnmvq_f64: +    Int = Intrinsic::aarch64_neon_vminnmv; +    AcrossVec = true; ExtendEle = false; s = "vminnmv"; break; +  // Scalar Integer Saturating Doubling Multiply Half High +  case AArch64::BI__builtin_neon_vqdmulhh_s16: +  case AArch64::BI__builtin_neon_vqdmulhs_s32: +    Int = Intrinsic::arm_neon_vqdmulh; +    s = "vqdmulh"; OverloadInt = true; break; +  // Scalar Integer Saturating Rounding Doubling Multiply Half High +  case AArch64::BI__builtin_neon_vqrdmulhh_s16: +  case AArch64::BI__builtin_neon_vqrdmulhs_s32: +    Int = Intrinsic::arm_neon_vqrdmulh; +    s = "vqrdmulh"; OverloadInt = true; break; +  // Scalar Floating-point Reciprocal Step and +  case AArch64::BI__builtin_neon_vrecpss_f32: +  case AArch64::BI__builtin_neon_vrecpsd_f64: +    Int = Intrinsic::arm_neon_vrecps; +    s = "vrecps"; OverloadInt = true; break; +  // Scalar Floating-point Reciprocal Square Root Step +  case AArch64::BI__builtin_neon_vrsqrtss_f32: +  case AArch64::BI__builtin_neon_vrsqrtsd_f64: +    Int = Intrinsic::arm_neon_vrsqrts; +    s = "vrsqrts"; OverloadInt = true; break; +  // Scalar Signed Integer Convert To Floating-point +  case AArch64::BI__builtin_neon_vcvts_f32_s32: +    Int = Intrinsic::aarch64_neon_vcvtf32_s32, +    s = "vcvtf"; OverloadInt = false; break; +  case AArch64::BI__builtin_neon_vcvtd_f64_s64: +    Int = Intrinsic::aarch64_neon_vcvtf64_s64, +    s = "vcvtf"; OverloadInt = false; break; +  // Scalar Unsigned Integer Convert To Floating-point +  case AArch64::BI__builtin_neon_vcvts_f32_u32: +    Int = Intrinsic::aarch64_neon_vcvtf32_u32, +    s = "vcvtf"; OverloadInt = false; break; +  case AArch64::BI__builtin_neon_vcvtd_f64_u64: +    Int = Intrinsic::aarch64_neon_vcvtf64_u64, +    s = "vcvtf"; OverloadInt = false; break; +  // Scalar Floating-point Converts +  case AArch64::BI__builtin_neon_vcvtxd_f32_f64: +    Int = Intrinsic::aarch64_neon_fcvtxn; +    s = "vcvtxn"; OverloadCvtInt = true; break; +  case AArch64::BI__builtin_neon_vcvtas_s32_f32: +  case AArch64::BI__builtin_neon_vcvtad_s64_f64: +    Int = Intrinsic::aarch64_neon_fcvtas; +    s = "vcvtas"; OverloadCvtInt = true; break; +  case AArch64::BI__builtin_neon_vcvtas_u32_f32: +  case AArch64::BI__builtin_neon_vcvtad_u64_f64: +    Int = Intrinsic::aarch64_neon_fcvtau; +    s = "vcvtau"; OverloadCvtInt = true; break; +  case AArch64::BI__builtin_neon_vcvtms_s32_f32: +  case AArch64::BI__builtin_neon_vcvtmd_s64_f64: +    Int = Intrinsic::aarch64_neon_fcvtms; +    s = "vcvtms"; OverloadCvtInt = true; break; +  case AArch64::BI__builtin_neon_vcvtms_u32_f32: +  case AArch64::BI__builtin_neon_vcvtmd_u64_f64: +    Int = Intrinsic::aarch64_neon_fcvtmu; +    s = "vcvtmu"; OverloadCvtInt = true; break; +  case AArch64::BI__builtin_neon_vcvtns_s32_f32: +  case AArch64::BI__builtin_neon_vcvtnd_s64_f64: +    Int = Intrinsic::aarch64_neon_fcvtns; +    s = "vcvtns"; OverloadCvtInt = true; break; +  case AArch64::BI__builtin_neon_vcvtns_u32_f32: +  case AArch64::BI__builtin_neon_vcvtnd_u64_f64: +    Int = Intrinsic::aarch64_neon_fcvtnu; +    s = "vcvtnu"; OverloadCvtInt = true; break; +  case AArch64::BI__builtin_neon_vcvtps_s32_f32: +  case AArch64::BI__builtin_neon_vcvtpd_s64_f64: +    Int = Intrinsic::aarch64_neon_fcvtps; +    s = "vcvtps"; OverloadCvtInt = true; break; +  case AArch64::BI__builtin_neon_vcvtps_u32_f32: +  case AArch64::BI__builtin_neon_vcvtpd_u64_f64: +    Int = Intrinsic::aarch64_neon_fcvtpu; +    s = "vcvtpu"; OverloadCvtInt = true; break; +  case AArch64::BI__builtin_neon_vcvts_s32_f32: +  case AArch64::BI__builtin_neon_vcvtd_s64_f64: +    Int = Intrinsic::aarch64_neon_fcvtzs; +    s = "vcvtzs"; OverloadCvtInt = true; break; +  case AArch64::BI__builtin_neon_vcvts_u32_f32: +  case AArch64::BI__builtin_neon_vcvtd_u64_f64: +    Int = Intrinsic::aarch64_neon_fcvtzu; +    s = "vcvtzu"; OverloadCvtInt = true; break; +  // Scalar Floating-point Reciprocal Estimate +  case AArch64::BI__builtin_neon_vrecpes_f32: +  case AArch64::BI__builtin_neon_vrecped_f64: +    Int = Intrinsic::arm_neon_vrecpe; +    s = "vrecpe"; OverloadInt = true; break; +  // Scalar Floating-point Reciprocal Exponent +  case AArch64::BI__builtin_neon_vrecpxs_f32: +  case AArch64::BI__builtin_neon_vrecpxd_f64: +    Int = Intrinsic::aarch64_neon_vrecpx; +    s = "vrecpx"; OverloadInt = true; break; +  // Scalar Floating-point Reciprocal Square Root Estimate +  case AArch64::BI__builtin_neon_vrsqrtes_f32: +  case AArch64::BI__builtin_neon_vrsqrted_f64: +    Int = Intrinsic::arm_neon_vrsqrte; +    s = "vrsqrte"; OverloadInt = true; break; +  // Scalar Compare Equal +  case AArch64::BI__builtin_neon_vceqd_s64: +  case AArch64::BI__builtin_neon_vceqd_u64: +    Int = Intrinsic::aarch64_neon_vceq; s = "vceq"; +    OverloadCmpInt = true; break; +  // Scalar Compare Equal To Zero +  case AArch64::BI__builtin_neon_vceqzd_s64: +  case AArch64::BI__builtin_neon_vceqzd_u64: +    Int = Intrinsic::aarch64_neon_vceq; s = "vceq"; +    // Add implicit zero operand. +    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType())); +    OverloadCmpInt = true; break; +  // Scalar Compare Greater Than or Equal +  case AArch64::BI__builtin_neon_vcged_s64: +    Int = Intrinsic::aarch64_neon_vcge; s = "vcge"; +    OverloadCmpInt = true; break; +  case AArch64::BI__builtin_neon_vcged_u64: +    Int = Intrinsic::aarch64_neon_vchs; s = "vcge"; +    OverloadCmpInt = true; break; +  // Scalar Compare Greater Than or Equal To Zero +  case AArch64::BI__builtin_neon_vcgezd_s64: +    Int = Intrinsic::aarch64_neon_vcge; s = "vcge"; +    // Add implicit zero operand. +    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType())); +    OverloadCmpInt = true; break; +  // Scalar Compare Greater Than +  case AArch64::BI__builtin_neon_vcgtd_s64: +    Int = Intrinsic::aarch64_neon_vcgt; s = "vcgt"; +    OverloadCmpInt = true; break; +  case AArch64::BI__builtin_neon_vcgtd_u64: +    Int = Intrinsic::aarch64_neon_vchi; s = "vcgt"; +    OverloadCmpInt = true; break; +  // Scalar Compare Greater Than Zero +  case AArch64::BI__builtin_neon_vcgtzd_s64: +    Int = Intrinsic::aarch64_neon_vcgt; s = "vcgt"; +    // Add implicit zero operand. +    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType())); +    OverloadCmpInt = true; break; +  // Scalar Compare Less Than or Equal +  case AArch64::BI__builtin_neon_vcled_s64: +    Int = Intrinsic::aarch64_neon_vcge; s = "vcge"; +    OverloadCmpInt = true; std::swap(Ops[0], Ops[1]); break; +  case AArch64::BI__builtin_neon_vcled_u64: +    Int = Intrinsic::aarch64_neon_vchs; s = "vchs"; +    OverloadCmpInt = true; std::swap(Ops[0], Ops[1]); break; +  // Scalar Compare Less Than or Equal To Zero +  case AArch64::BI__builtin_neon_vclezd_s64: +    Int = Intrinsic::aarch64_neon_vclez; s = "vcle"; +    // Add implicit zero operand. +    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType())); +    OverloadCmpInt = true; break; +  // Scalar Compare Less Than +  case AArch64::BI__builtin_neon_vcltd_s64: +    Int = Intrinsic::aarch64_neon_vcgt; s = "vcgt"; +    OverloadCmpInt = true; std::swap(Ops[0], Ops[1]); break; +  case AArch64::BI__builtin_neon_vcltd_u64: +    Int = Intrinsic::aarch64_neon_vchi; s = "vchi"; +    OverloadCmpInt = true; std::swap(Ops[0], Ops[1]); break; +  // Scalar Compare Less Than Zero +  case AArch64::BI__builtin_neon_vcltzd_s64: +    Int = Intrinsic::aarch64_neon_vcltz; s = "vclt"; +    // Add implicit zero operand. +    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType())); +    OverloadCmpInt = true; break; +  // Scalar Floating-point Compare Equal +  case AArch64::BI__builtin_neon_vceqs_f32: +  case AArch64::BI__builtin_neon_vceqd_f64: +    Int = Intrinsic::aarch64_neon_vceq; s = "vceq"; +    OverloadCmpInt = true; break; +  // Scalar Floating-point Compare Equal To Zero +  case AArch64::BI__builtin_neon_vceqzs_f32: +  case AArch64::BI__builtin_neon_vceqzd_f64: +    Int = Intrinsic::aarch64_neon_vceq; s = "vceq"; +    // Add implicit zero operand. +    Ops.push_back(llvm::Constant::getNullValue(CGF.FloatTy)); +    IsFpCmpZInt = true; +    OverloadCmpInt = true; break; +  // Scalar Floating-point Compare Greater Than Or Equal +  case AArch64::BI__builtin_neon_vcges_f32: +  case AArch64::BI__builtin_neon_vcged_f64: +    Int = Intrinsic::aarch64_neon_vcge; s = "vcge"; +    OverloadCmpInt = true; break; +  // Scalar Floating-point Compare Greater Than Or Equal To Zero +  case AArch64::BI__builtin_neon_vcgezs_f32: +  case AArch64::BI__builtin_neon_vcgezd_f64: +    Int = Intrinsic::aarch64_neon_vcge; s = "vcge"; +    // Add implicit zero operand. +    Ops.push_back(llvm::Constant::getNullValue(CGF.FloatTy)); +    IsFpCmpZInt = true; +    OverloadCmpInt = true; break; +  // Scalar Floating-point Compare Greather Than +  case AArch64::BI__builtin_neon_vcgts_f32: +  case AArch64::BI__builtin_neon_vcgtd_f64: +    Int = Intrinsic::aarch64_neon_vcgt; s = "vcgt"; +    OverloadCmpInt = true; break; +  // Scalar Floating-point Compare Greather Than Zero +  case AArch64::BI__builtin_neon_vcgtzs_f32: +  case AArch64::BI__builtin_neon_vcgtzd_f64: +    Int = Intrinsic::aarch64_neon_vcgt; s = "vcgt"; +    // Add implicit zero operand. +    Ops.push_back(llvm::Constant::getNullValue(CGF.FloatTy)); +    IsFpCmpZInt = true; +    OverloadCmpInt = true; break; +  // Scalar Floating-point Compare Less Than or Equal +  case AArch64::BI__builtin_neon_vcles_f32: +  case AArch64::BI__builtin_neon_vcled_f64: +    Int = Intrinsic::aarch64_neon_vcge; s = "vcge"; +    OverloadCmpInt = true; break; +  // Scalar Floating-point Compare Less Than Or Equal To Zero +  case AArch64::BI__builtin_neon_vclezs_f32: +  case AArch64::BI__builtin_neon_vclezd_f64: +    Int = Intrinsic::aarch64_neon_vclez; s = "vcle"; +    // Add implicit zero operand. +    Ops.push_back(llvm::Constant::getNullValue(CGF.FloatTy)); +    IsFpCmpZInt = true; +    OverloadCmpInt = true; break; +  // Scalar Floating-point Compare Less Than Zero +  case AArch64::BI__builtin_neon_vclts_f32: +  case AArch64::BI__builtin_neon_vcltd_f64: +    Int = Intrinsic::aarch64_neon_vcgt; s = "vcgt"; +    OverloadCmpInt = true; std::swap(Ops[0], Ops[1]); break; +  // Scalar Floating-point Compare Less Than Zero +  case AArch64::BI__builtin_neon_vcltzs_f32: +  case AArch64::BI__builtin_neon_vcltzd_f64: +    Int = Intrinsic::aarch64_neon_vcltz; s = "vclt"; +    // Add implicit zero operand. +    Ops.push_back(llvm::Constant::getNullValue(CGF.FloatTy)); +    IsFpCmpZInt = true; +    OverloadCmpInt = true; break; +  // Scalar Floating-point Absolute Compare Greater Than Or Equal +  case AArch64::BI__builtin_neon_vcages_f32: +  case AArch64::BI__builtin_neon_vcaged_f64: +    Int = Intrinsic::aarch64_neon_vcage; s = "vcage"; +    OverloadCmpInt = true; break; +  // Scalar Floating-point Absolute Compare Greater Than +  case AArch64::BI__builtin_neon_vcagts_f32: +  case AArch64::BI__builtin_neon_vcagtd_f64: +    Int = Intrinsic::aarch64_neon_vcagt; s = "vcagt"; +    OverloadCmpInt = true; break; +  // Scalar Floating-point Absolute Compare Less Than Or Equal +  case AArch64::BI__builtin_neon_vcales_f32: +  case AArch64::BI__builtin_neon_vcaled_f64: +    Int = Intrinsic::aarch64_neon_vcage; s = "vcage"; +    OverloadCmpInt = true; std::swap(Ops[0], Ops[1]); break; +  // Scalar Floating-point Absolute Compare Less Than +  case AArch64::BI__builtin_neon_vcalts_f32: +  case AArch64::BI__builtin_neon_vcaltd_f64: +    Int = Intrinsic::aarch64_neon_vcagt; s = "vcalt"; +    OverloadCmpInt = true; std::swap(Ops[0], Ops[1]); break; +  // Scalar Compare Bitwise Test Bits +  case AArch64::BI__builtin_neon_vtstd_s64: +  case AArch64::BI__builtin_neon_vtstd_u64: +    Int = Intrinsic::aarch64_neon_vtstd; s = "vtst"; +    OverloadCmpInt = true; break; +  // Scalar Absolute Value +  case AArch64::BI__builtin_neon_vabsd_s64: +    Int = Intrinsic::aarch64_neon_vabs; +    s = "vabs"; OverloadInt = false; break; +  // Scalar Absolute Difference +  case AArch64::BI__builtin_neon_vabds_f32: +  case AArch64::BI__builtin_neon_vabdd_f64: +    Int = Intrinsic::aarch64_neon_vabd; +    s = "vabd"; OverloadInt = true; break; +  // Scalar Signed Saturating Absolute Value +  case AArch64::BI__builtin_neon_vqabsb_s8: +  case AArch64::BI__builtin_neon_vqabsh_s16: +  case AArch64::BI__builtin_neon_vqabss_s32: +  case AArch64::BI__builtin_neon_vqabsd_s64: +    Int = Intrinsic::arm_neon_vqabs; +    s = "vqabs"; OverloadInt = true; break; +  // Scalar Negate +  case AArch64::BI__builtin_neon_vnegd_s64: +    Int = Intrinsic::aarch64_neon_vneg; +    s = "vneg"; OverloadInt = false; break; +  // Scalar Signed Saturating Negate +  case AArch64::BI__builtin_neon_vqnegb_s8: +  case AArch64::BI__builtin_neon_vqnegh_s16: +  case AArch64::BI__builtin_neon_vqnegs_s32: +  case AArch64::BI__builtin_neon_vqnegd_s64: +    Int = Intrinsic::arm_neon_vqneg; +    s = "vqneg"; OverloadInt = true; break; +  // Scalar Signed Saturating Accumulated of Unsigned Value +  case AArch64::BI__builtin_neon_vuqaddb_s8: +  case AArch64::BI__builtin_neon_vuqaddh_s16: +  case AArch64::BI__builtin_neon_vuqadds_s32: +  case AArch64::BI__builtin_neon_vuqaddd_s64: +    Int = Intrinsic::aarch64_neon_vuqadd; +    s = "vuqadd"; OverloadInt = true; break; +  // Scalar Unsigned Saturating Accumulated of Signed Value +  case AArch64::BI__builtin_neon_vsqaddb_u8: +  case AArch64::BI__builtin_neon_vsqaddh_u16: +  case AArch64::BI__builtin_neon_vsqadds_u32: +  case AArch64::BI__builtin_neon_vsqaddd_u64: +    Int = Intrinsic::aarch64_neon_vsqadd; +    s = "vsqadd"; OverloadInt = true; break; +  // Signed Saturating Doubling Multiply-Add Long +  case AArch64::BI__builtin_neon_vqdmlalh_s16: +  case AArch64::BI__builtin_neon_vqdmlals_s32: +    Int = Intrinsic::aarch64_neon_vqdmlal; +    s = "vqdmlal"; OverloadWideInt = true; break; +  // Signed Saturating Doubling Multiply-Subtract Long +  case AArch64::BI__builtin_neon_vqdmlslh_s16: +  case AArch64::BI__builtin_neon_vqdmlsls_s32: +    Int = Intrinsic::aarch64_neon_vqdmlsl; +    s = "vqdmlsl"; OverloadWideInt = true; break; +  // Signed Saturating Doubling Multiply Long +  case AArch64::BI__builtin_neon_vqdmullh_s16: +  case AArch64::BI__builtin_neon_vqdmulls_s32: +    Int = Intrinsic::arm_neon_vqdmull; +    s = "vqdmull"; OverloadWideInt = true; break; +  // Scalar Signed Saturating Extract Unsigned Narrow +  case AArch64::BI__builtin_neon_vqmovunh_s16: +  case AArch64::BI__builtin_neon_vqmovuns_s32: +  case AArch64::BI__builtin_neon_vqmovund_s64: +    Int = Intrinsic::arm_neon_vqmovnsu; +    s = "vqmovun"; OverloadNarrowInt = true; break; +  // Scalar Signed Saturating Extract Narrow +  case AArch64::BI__builtin_neon_vqmovnh_s16: +  case AArch64::BI__builtin_neon_vqmovns_s32: +  case AArch64::BI__builtin_neon_vqmovnd_s64: +    Int = Intrinsic::arm_neon_vqmovns; +    s = "vqmovn"; OverloadNarrowInt = true; break; +  // Scalar Unsigned Saturating Extract Narrow +  case AArch64::BI__builtin_neon_vqmovnh_u16: +  case AArch64::BI__builtin_neon_vqmovns_u32: +  case AArch64::BI__builtin_neon_vqmovnd_u64: +    Int = Intrinsic::arm_neon_vqmovnu; +    s = "vqmovn"; OverloadNarrowInt = true; break; +  // Scalar Signed Shift Right (Immediate) +  case AArch64::BI__builtin_neon_vshrd_n_s64: +    Int = Intrinsic::aarch64_neon_vshrds_n; +    s = "vsshr"; OverloadInt = false; break; +  // Scalar Unsigned Shift Right (Immediate) +  case AArch64::BI__builtin_neon_vshrd_n_u64: +    Int = Intrinsic::aarch64_neon_vshrdu_n; +    s = "vushr"; OverloadInt = false; break; +  // Scalar Signed Rounding Shift Right (Immediate) +  case AArch64::BI__builtin_neon_vrshrd_n_s64: +    Int = Intrinsic::aarch64_neon_vsrshr; +    s = "vsrshr"; OverloadInt = true; break; +  // Scalar Unsigned Rounding Shift Right (Immediate) +  case AArch64::BI__builtin_neon_vrshrd_n_u64: +    Int = Intrinsic::aarch64_neon_vurshr; +    s = "vurshr"; OverloadInt = true; break; +  // Scalar Signed Shift Right and Accumulate (Immediate) +  case AArch64::BI__builtin_neon_vsrad_n_s64: +    Int = Intrinsic::aarch64_neon_vsrads_n; +    s = "vssra"; OverloadInt = false; break; +  // Scalar Unsigned Shift Right and Accumulate (Immediate) +  case AArch64::BI__builtin_neon_vsrad_n_u64: +    Int = Intrinsic::aarch64_neon_vsradu_n; +    s = "vusra"; OverloadInt = false; break; +  // Scalar Signed Rounding Shift Right and Accumulate (Immediate) +  case AArch64::BI__builtin_neon_vrsrad_n_s64: +    Int = Intrinsic::aarch64_neon_vrsrads_n; +    s = "vsrsra"; OverloadInt = false; break; +  // Scalar Unsigned Rounding Shift Right and Accumulate (Immediate) +  case AArch64::BI__builtin_neon_vrsrad_n_u64: +    Int = Intrinsic::aarch64_neon_vrsradu_n; +    s = "vursra"; OverloadInt = false; break; +  // Scalar Signed/Unsigned Shift Left (Immediate) +  case AArch64::BI__builtin_neon_vshld_n_s64: +  case AArch64::BI__builtin_neon_vshld_n_u64: +    Int = Intrinsic::aarch64_neon_vshld_n; +    s = "vshl"; OverloadInt = false; break; +  // Signed Saturating Shift Left (Immediate) +  case AArch64::BI__builtin_neon_vqshlb_n_s8: +  case AArch64::BI__builtin_neon_vqshlh_n_s16: +  case AArch64::BI__builtin_neon_vqshls_n_s32: +  case AArch64::BI__builtin_neon_vqshld_n_s64: +    Int = Intrinsic::aarch64_neon_vqshls_n; +    s = "vsqshl"; OverloadInt = true; break; +  // Unsigned Saturating Shift Left (Immediate) +  case AArch64::BI__builtin_neon_vqshlb_n_u8: +  case AArch64::BI__builtin_neon_vqshlh_n_u16: +  case AArch64::BI__builtin_neon_vqshls_n_u32: +  case AArch64::BI__builtin_neon_vqshld_n_u64: +    Int = Intrinsic::aarch64_neon_vqshlu_n; +    s = "vuqshl"; OverloadInt = true; break; +  // Signed Saturating Shift Left Unsigned (Immediate) +  case AArch64::BI__builtin_neon_vqshlub_n_s8: +  case AArch64::BI__builtin_neon_vqshluh_n_s16: +  case AArch64::BI__builtin_neon_vqshlus_n_s32: +  case AArch64::BI__builtin_neon_vqshlud_n_s64: +    Int = Intrinsic::aarch64_neon_vsqshlu; +    s = "vsqshlu"; OverloadInt = true; break; +  // Shift Right And Insert (Immediate) +  case AArch64::BI__builtin_neon_vsrid_n_s64: +  case AArch64::BI__builtin_neon_vsrid_n_u64: +    Int = Intrinsic::aarch64_neon_vsri; +    s = "vsri"; OverloadInt = true; break; +  // Shift Left And Insert (Immediate) +  case AArch64::BI__builtin_neon_vslid_n_s64: +  case AArch64::BI__builtin_neon_vslid_n_u64: +    Int = Intrinsic::aarch64_neon_vsli; +    s = "vsli"; OverloadInt = true; break; +  // Signed Saturating Shift Right Narrow (Immediate) +  case AArch64::BI__builtin_neon_vqshrnh_n_s16: +  case AArch64::BI__builtin_neon_vqshrns_n_s32: +  case AArch64::BI__builtin_neon_vqshrnd_n_s64: +    Int = Intrinsic::aarch64_neon_vsqshrn; +    s = "vsqshrn"; OverloadInt = true; break; +  // Unsigned Saturating Shift Right Narrow (Immediate) +  case AArch64::BI__builtin_neon_vqshrnh_n_u16: +  case AArch64::BI__builtin_neon_vqshrns_n_u32: +  case AArch64::BI__builtin_neon_vqshrnd_n_u64: +    Int = Intrinsic::aarch64_neon_vuqshrn; +    s = "vuqshrn"; OverloadInt = true; break; +  // Signed Saturating Rounded Shift Right Narrow (Immediate) +  case AArch64::BI__builtin_neon_vqrshrnh_n_s16: +  case AArch64::BI__builtin_neon_vqrshrns_n_s32: +  case AArch64::BI__builtin_neon_vqrshrnd_n_s64: +    Int = Intrinsic::aarch64_neon_vsqrshrn; +    s = "vsqrshrn"; OverloadInt = true; break; +  // Unsigned Saturating Rounded Shift Right Narrow (Immediate) +  case AArch64::BI__builtin_neon_vqrshrnh_n_u16: +  case AArch64::BI__builtin_neon_vqrshrns_n_u32: +  case AArch64::BI__builtin_neon_vqrshrnd_n_u64: +    Int = Intrinsic::aarch64_neon_vuqrshrn; +    s = "vuqrshrn"; OverloadInt = true; break; +  // Signed Saturating Shift Right Unsigned Narrow (Immediate) +  case AArch64::BI__builtin_neon_vqshrunh_n_s16: +  case AArch64::BI__builtin_neon_vqshruns_n_s32: +  case AArch64::BI__builtin_neon_vqshrund_n_s64: +    Int = Intrinsic::aarch64_neon_vsqshrun; +    s = "vsqshrun"; OverloadInt = true; break; +  // Signed Saturating Rounded Shift Right Unsigned Narrow (Immediate) +  case AArch64::BI__builtin_neon_vqrshrunh_n_s16: +  case AArch64::BI__builtin_neon_vqrshruns_n_s32: +  case AArch64::BI__builtin_neon_vqrshrund_n_s64: +    Int = Intrinsic::aarch64_neon_vsqrshrun; +    s = "vsqrshrun"; OverloadInt = true; break; +  // Scalar Signed Fixed-point Convert To Floating-Point (Immediate) +  case AArch64::BI__builtin_neon_vcvts_n_f32_s32: +    Int = Intrinsic::aarch64_neon_vcvtf32_n_s32; +    s = "vcvtf"; OverloadInt = false; break; +  case AArch64::BI__builtin_neon_vcvtd_n_f64_s64: +    Int = Intrinsic::aarch64_neon_vcvtf64_n_s64; +    s = "vcvtf"; OverloadInt = false; break; +  // Scalar Unsigned Fixed-point Convert To Floating-Point (Immediate) +  case AArch64::BI__builtin_neon_vcvts_n_f32_u32: +    Int = Intrinsic::aarch64_neon_vcvtf32_n_u32; +    s = "vcvtf"; OverloadInt = false; break; +  case AArch64::BI__builtin_neon_vcvtd_n_f64_u64: +    Int = Intrinsic::aarch64_neon_vcvtf64_n_u64; +    s = "vcvtf"; OverloadInt = false; break; +  // Scalar Floating-point Convert To Signed Fixed-point (Immediate) +  case AArch64::BI__builtin_neon_vcvts_n_s32_f32: +    Int = Intrinsic::aarch64_neon_vcvts_n_s32_f32; +    s = "fcvtzs"; OverloadInt = false; break; +  case AArch64::BI__builtin_neon_vcvtd_n_s64_f64: +    Int = Intrinsic::aarch64_neon_vcvtd_n_s64_f64; +    s = "fcvtzs"; OverloadInt = false; break; +  // Scalar Floating-point Convert To Unsigned Fixed-point (Immediate) +  case AArch64::BI__builtin_neon_vcvts_n_u32_f32: +    Int = Intrinsic::aarch64_neon_vcvts_n_u32_f32; +    s = "fcvtzu"; OverloadInt = false; break; +  case AArch64::BI__builtin_neon_vcvtd_n_u64_f64: +    Int = Intrinsic::aarch64_neon_vcvtd_n_u64_f64; +    s = "fcvtzu"; OverloadInt = false; break; +  } + +  if (!Int) +    return 0; + +  // AArch64 scalar builtin that returns scalar type +  // and should be mapped to AArch64 intrinsic that returns +  // one-element vector type. +  Function *F = 0; +  if (AcrossVec) { +    // Gen arg type +    const Expr *Arg = E->getArg(E->getNumArgs()-1); +    llvm::Type *Ty = CGF.ConvertType(Arg->getType()); +    llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); +    llvm::Type *ETy = VTy->getElementType(); +    llvm::VectorType *RTy = llvm::VectorType::get(ETy, 1); +   +    if (ExtendEle) { +      assert(!ETy->isFloatingPointTy()); +      RTy = llvm::VectorType::getExtendedElementVectorType(RTy); +    } + +    llvm::Type *Tys[2] = {RTy, VTy}; +    F = CGF.CGM.getIntrinsic(Int, Tys); +    assert(E->getNumArgs() == 1); +  } else if (OverloadInt) { +    // Determine the type of this overloaded AArch64 intrinsic +    llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType()); +    llvm::VectorType *VTy = llvm::VectorType::get(Ty, 1); +    assert(VTy); + +    F = CGF.CGM.getIntrinsic(Int, VTy); +  } else if (OverloadWideInt || OverloadNarrowInt) { +    // Determine the type of this overloaded AArch64 intrinsic +    const Expr *Arg = E->getArg(E->getNumArgs()-1); +    llvm::Type *Ty = CGF.ConvertType(Arg->getType()); +    llvm::VectorType *VTy = llvm::VectorType::get(Ty, 1); +    llvm::VectorType *RTy = OverloadWideInt ?  +      llvm::VectorType::getExtendedElementVectorType(VTy) : +      llvm::VectorType::getTruncatedElementVectorType(VTy); +    F = CGF.CGM.getIntrinsic(Int, RTy); +  } else if (OverloadCmpInt) { +    // Determine the types of this overloaded AArch64 intrinsic +    SmallVector<llvm::Type *, 3> Tys; +    const Expr *Arg = E->getArg(E->getNumArgs()-1); +    llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType()); +    llvm::VectorType *VTy = llvm::VectorType::get(Ty, 1); +    Tys.push_back(VTy); +    Ty = CGF.ConvertType(Arg->getType()); +    VTy = llvm::VectorType::get(Ty, 1); +    Tys.push_back(VTy); +    if(IsFpCmpZInt) +      VTy = llvm::VectorType::get(CGF.FloatTy, 1); +    Tys.push_back(VTy); + +    F = CGF.CGM.getIntrinsic(Int, Tys); +  } else if (OverloadCvtInt) { +    // Determine the types of this overloaded AArch64 intrinsic +    SmallVector<llvm::Type *, 2> Tys; +    const Expr *Arg = E->getArg(E->getNumArgs()-1); +    llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType()); +    llvm::VectorType *VTy = llvm::VectorType::get(Ty, 1); +    Tys.push_back(VTy); +    Ty = CGF.ConvertType(Arg->getType()); +    VTy = llvm::VectorType::get(Ty, 1); +    Tys.push_back(VTy); + +    F = CGF.CGM.getIntrinsic(Int, Tys); +  } else +    F = CGF.CGM.getIntrinsic(Int); + +  Value *Result = CGF.EmitNeonCall(F, Ops, s); +  llvm::Type *ResultType = CGF.ConvertType(E->getType()); +  // AArch64 intrinsic one-element vector type cast to +  // scalar type expected by the builtin +  return CGF.Builder.CreateBitCast(Result, ResultType, s); +} + +Value *CodeGenFunction::EmitAArch64CompareBuiltinExpr( +    Value *Op, llvm::Type *Ty, const CmpInst::Predicate Fp, +    const CmpInst::Predicate Ip, const Twine &Name) { +  llvm::Type *OTy = ((llvm::User *)Op)->getOperand(0)->getType(); +  if (OTy->isPointerTy()) +    OTy = Ty; +  Op = Builder.CreateBitCast(Op, OTy); +  if (((llvm::VectorType *)OTy)->getElementType()->isFloatingPointTy()) { +    Op = Builder.CreateFCmp(Fp, Op, ConstantAggregateZero::get(OTy)); +  } else { +    Op = Builder.CreateICmp(Ip, Op, ConstantAggregateZero::get(OTy)); +  } +  return Builder.CreateZExt(Op, Ty, Name); +} + +static Value *packTBLDVectorList(CodeGenFunction &CGF, ArrayRef<Value *> Ops, +                                 Value *ExtOp, Value *IndexOp, +                                 llvm::Type *ResTy, unsigned IntID, +                                 const char *Name) { +  SmallVector<Value *, 2> TblOps; +  if (ExtOp) +    TblOps.push_back(ExtOp); + +  // Build a vector containing sequential number like (0, 1, 2, ..., 15)   +  SmallVector<Constant*, 16> Indices; +  llvm::VectorType *TblTy = cast<llvm::VectorType>(Ops[0]->getType()); +  for (unsigned i = 0, e = TblTy->getNumElements(); i != e; ++i) { +    Indices.push_back(ConstantInt::get(CGF.Int32Ty, 2*i)); +    Indices.push_back(ConstantInt::get(CGF.Int32Ty, 2*i+1)); +  } +  Value *SV = llvm::ConstantVector::get(Indices); + +  int PairPos = 0, End = Ops.size() - 1; +  while (PairPos < End) { +    TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], +                                                     Ops[PairPos+1], SV, Name)); +    PairPos += 2; +  } + +  // If there's an odd number of 64-bit lookup table, fill the high 64-bit +  // of the 128-bit lookup table with zero. +  if (PairPos == End) { +    Value *ZeroTbl = ConstantAggregateZero::get(TblTy); +    TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], +                                                     ZeroTbl, SV, Name)); +  } + +  TblTy = llvm::VectorType::get(TblTy->getElementType(), +                                2*TblTy->getNumElements()); +  llvm::Type *Tys[2] = { ResTy, TblTy }; + +  Function *TblF; +  TblOps.push_back(IndexOp); +  TblF = CGF.CGM.getIntrinsic(IntID, Tys); +   +  return CGF.EmitNeonCall(TblF, TblOps, Name); +} + +static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, +                                        unsigned BuiltinID, +                                        const CallExpr *E) { +  unsigned int Int = 0; +  const char *s = NULL; + +  unsigned TblPos; +  switch (BuiltinID) { +  default: +    return 0; +  case AArch64::BI__builtin_neon_vtbl1_v: +  case AArch64::BI__builtin_neon_vqtbl1_v: +  case AArch64::BI__builtin_neon_vqtbl1q_v: +  case AArch64::BI__builtin_neon_vtbl2_v: +  case AArch64::BI__builtin_neon_vqtbl2_v: +  case AArch64::BI__builtin_neon_vqtbl2q_v: +  case AArch64::BI__builtin_neon_vtbl3_v: +  case AArch64::BI__builtin_neon_vqtbl3_v: +  case AArch64::BI__builtin_neon_vqtbl3q_v: +  case AArch64::BI__builtin_neon_vtbl4_v: +  case AArch64::BI__builtin_neon_vqtbl4_v: +  case AArch64::BI__builtin_neon_vqtbl4q_v: +    TblPos = 0; +    break; +  case AArch64::BI__builtin_neon_vtbx1_v: +  case AArch64::BI__builtin_neon_vqtbx1_v: +  case AArch64::BI__builtin_neon_vqtbx1q_v: +  case AArch64::BI__builtin_neon_vtbx2_v: +  case AArch64::BI__builtin_neon_vqtbx2_v: +  case AArch64::BI__builtin_neon_vqtbx2q_v: +  case AArch64::BI__builtin_neon_vtbx3_v: +  case AArch64::BI__builtin_neon_vqtbx3_v: +  case AArch64::BI__builtin_neon_vqtbx3q_v: +  case AArch64::BI__builtin_neon_vtbx4_v: +  case AArch64::BI__builtin_neon_vqtbx4_v: +  case AArch64::BI__builtin_neon_vqtbx4q_v: +    TblPos = 1; +    break; +  } + +  assert(E->getNumArgs() >= 3); + +  // Get the last argument, which specifies the vector type. +  llvm::APSInt Result; +  const Expr *Arg = E->getArg(E->getNumArgs() - 1); +  if (!Arg->isIntegerConstantExpr(Result, CGF.getContext())) +    return 0; + +  // Determine the type of this overloaded NEON intrinsic. +  NeonTypeFlags Type(Result.getZExtValue()); +  llvm::VectorType *VTy = GetNeonType(&CGF, Type); +  llvm::Type *Ty = VTy; +  if (!Ty) +    return 0; + +  SmallVector<Value *, 4> Ops; +  for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { +    Ops.push_back(CGF.EmitScalarExpr(E->getArg(i))); +  } + +  Arg = E->getArg(TblPos); +  llvm::Type *TblTy = CGF.ConvertType(Arg->getType()); +  llvm::VectorType *VTblTy = cast<llvm::VectorType>(TblTy); +  llvm::Type *Tys[2] = { Ty, VTblTy }; +  unsigned nElts = VTy->getNumElements();   + +  // AArch64 scalar builtins are not overloaded, they do not have an extra +  // argument that specifies the vector type, need to handle each case. +  SmallVector<Value *, 2> TblOps; +  switch (BuiltinID) { +  case AArch64::BI__builtin_neon_vtbl1_v: { +    TblOps.push_back(Ops[0]); +    return packTBLDVectorList(CGF, TblOps, 0, Ops[1], Ty, +                              Intrinsic::aarch64_neon_vtbl1, "vtbl1"); +  } +  case AArch64::BI__builtin_neon_vtbl2_v: { +    TblOps.push_back(Ops[0]); +    TblOps.push_back(Ops[1]); +    return packTBLDVectorList(CGF, TblOps, 0, Ops[2], Ty, +                              Intrinsic::aarch64_neon_vtbl1, "vtbl1"); +  } +  case AArch64::BI__builtin_neon_vtbl3_v: { +    TblOps.push_back(Ops[0]); +    TblOps.push_back(Ops[1]); +    TblOps.push_back(Ops[2]); +    return packTBLDVectorList(CGF, TblOps, 0, Ops[3], Ty, +                              Intrinsic::aarch64_neon_vtbl2, "vtbl2"); +  } +  case AArch64::BI__builtin_neon_vtbl4_v: { +    TblOps.push_back(Ops[0]); +    TblOps.push_back(Ops[1]); +    TblOps.push_back(Ops[2]); +    TblOps.push_back(Ops[3]); +    return packTBLDVectorList(CGF, TblOps, 0, Ops[4], Ty, +                              Intrinsic::aarch64_neon_vtbl2, "vtbl2"); +  } +  case AArch64::BI__builtin_neon_vtbx1_v: { +    TblOps.push_back(Ops[1]); +    Value *TblRes = packTBLDVectorList(CGF, TblOps, 0, Ops[2], Ty, +                                    Intrinsic::aarch64_neon_vtbl1, "vtbl1"); + +    llvm::Constant *Eight = ConstantInt::get(VTy->getElementType(), 8); +    Value* EightV = llvm::ConstantVector::getSplat(nElts, Eight); +    Value *CmpRes = CGF.Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[2], EightV); +    CmpRes = CGF.Builder.CreateSExt(CmpRes, Ty); + +    SmallVector<Value *, 4> BslOps; +    BslOps.push_back(CmpRes); +    BslOps.push_back(Ops[0]); +    BslOps.push_back(TblRes); +    Function *BslF = CGF.CGM.getIntrinsic(Intrinsic::arm_neon_vbsl, Ty); +    return CGF.EmitNeonCall(BslF, BslOps, "vbsl"); +  } +  case AArch64::BI__builtin_neon_vtbx2_v: { +    TblOps.push_back(Ops[1]); +    TblOps.push_back(Ops[2]); +    return packTBLDVectorList(CGF, TblOps, Ops[0], Ops[3], Ty, +                              Intrinsic::aarch64_neon_vtbx1, "vtbx1"); +  } +  case AArch64::BI__builtin_neon_vtbx3_v: { +    TblOps.push_back(Ops[1]); +    TblOps.push_back(Ops[2]); +    TblOps.push_back(Ops[3]); +    Value *TblRes = packTBLDVectorList(CGF, TblOps, 0, Ops[4], Ty, +                                       Intrinsic::aarch64_neon_vtbl2, "vtbl2"); + +    llvm::Constant *TwentyFour = ConstantInt::get(VTy->getElementType(), 24); +    Value* TwentyFourV = llvm::ConstantVector::getSplat(nElts, TwentyFour); +    Value *CmpRes = CGF.Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[4], +                                           TwentyFourV); +    CmpRes = CGF.Builder.CreateSExt(CmpRes, Ty); +   +    SmallVector<Value *, 4> BslOps; +    BslOps.push_back(CmpRes); +    BslOps.push_back(Ops[0]); +    BslOps.push_back(TblRes); +    Function *BslF = CGF.CGM.getIntrinsic(Intrinsic::arm_neon_vbsl, Ty); +    return CGF.EmitNeonCall(BslF, BslOps, "vbsl"); +  } +  case AArch64::BI__builtin_neon_vtbx4_v: { +    TblOps.push_back(Ops[1]); +    TblOps.push_back(Ops[2]); +    TblOps.push_back(Ops[3]); +    TblOps.push_back(Ops[4]); +    return packTBLDVectorList(CGF, TblOps, Ops[0], Ops[5], Ty, +                              Intrinsic::aarch64_neon_vtbx2, "vtbx2"); +  } +  case AArch64::BI__builtin_neon_vqtbl1_v: +  case AArch64::BI__builtin_neon_vqtbl1q_v: +    Int = Intrinsic::aarch64_neon_vtbl1; s = "vtbl1"; break; +  case AArch64::BI__builtin_neon_vqtbl2_v: +  case AArch64::BI__builtin_neon_vqtbl2q_v: { +    Int = Intrinsic::aarch64_neon_vtbl2; s = "vtbl2"; break; +  case AArch64::BI__builtin_neon_vqtbl3_v: +  case AArch64::BI__builtin_neon_vqtbl3q_v: +    Int = Intrinsic::aarch64_neon_vtbl3; s = "vtbl3"; break; +  case AArch64::BI__builtin_neon_vqtbl4_v: +  case AArch64::BI__builtin_neon_vqtbl4q_v: +    Int = Intrinsic::aarch64_neon_vtbl4; s = "vtbl4"; break; +  case AArch64::BI__builtin_neon_vqtbx1_v: +  case AArch64::BI__builtin_neon_vqtbx1q_v: +    Int = Intrinsic::aarch64_neon_vtbx1; s = "vtbx1"; break; +  case AArch64::BI__builtin_neon_vqtbx2_v: +  case AArch64::BI__builtin_neon_vqtbx2q_v: +    Int = Intrinsic::aarch64_neon_vtbx2; s = "vtbx2"; break; +  case AArch64::BI__builtin_neon_vqtbx3_v: +  case AArch64::BI__builtin_neon_vqtbx3q_v: +    Int = Intrinsic::aarch64_neon_vtbx3; s = "vtbx3"; break; +  case AArch64::BI__builtin_neon_vqtbx4_v: +  case AArch64::BI__builtin_neon_vqtbx4q_v: +    Int = Intrinsic::aarch64_neon_vtbx4; s = "vtbx4"; break; +  } +  } + +  if (!Int) +    return 0; + +  Function *F = CGF.CGM.getIntrinsic(Int, Tys); +  return CGF.EmitNeonCall(F, Ops, s); +} +  Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,                                                 const CallExpr *E) { +  // Process AArch64 scalar builtins +  if (Value *Result = EmitAArch64ScalarBuiltinExpr(*this, BuiltinID, E)) +    return Result; + +  // Process AArch64 table lookup builtins +  if (Value *Result = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E)) +    return Result; +    if (BuiltinID == AArch64::BI__clear_cache) {      assert(E->getNumArgs() == 2 &&             "Variadic __clear_cache slipped through on AArch64"); @@ -1639,17 +2897,1039 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,      return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);    } -  return 0; +  SmallVector<Value *, 4> Ops; +  llvm::Value *Align = 0; // Alignment for load/store +  for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { +    if (i == 0) { +      switch (BuiltinID) { +      case AArch64::BI__builtin_neon_vst1_x2_v: +      case AArch64::BI__builtin_neon_vst1q_x2_v: +      case AArch64::BI__builtin_neon_vst1_x3_v: +      case AArch64::BI__builtin_neon_vst1q_x3_v: +      case AArch64::BI__builtin_neon_vst1_x4_v: +      case AArch64::BI__builtin_neon_vst1q_x4_v: +      // Handle ld1/st1 lane in this function a little different from ARM. +      case AArch64::BI__builtin_neon_vld1_lane_v: +      case AArch64::BI__builtin_neon_vld1q_lane_v: +      case AArch64::BI__builtin_neon_vst1_lane_v: +      case AArch64::BI__builtin_neon_vst1q_lane_v: +        // Get the alignment for the argument in addition to the value; +        // we'll use it later. +        std::pair<llvm::Value *, unsigned> Src = +            EmitPointerWithAlignment(E->getArg(0)); +        Ops.push_back(Src.first); +        Align = Builder.getInt32(Src.second); +        continue; +      } +    } +    if (i == 1) { +      switch (BuiltinID) { +      case AArch64::BI__builtin_neon_vld1_x2_v: +      case AArch64::BI__builtin_neon_vld1q_x2_v: +      case AArch64::BI__builtin_neon_vld1_x3_v: +      case AArch64::BI__builtin_neon_vld1q_x3_v: +      case AArch64::BI__builtin_neon_vld1_x4_v: +      case AArch64::BI__builtin_neon_vld1q_x4_v: +      // Handle ld1/st1 dup lane in this function a little different from ARM. +      case AArch64::BI__builtin_neon_vld2_dup_v: +      case AArch64::BI__builtin_neon_vld2q_dup_v: +      case AArch64::BI__builtin_neon_vld3_dup_v: +      case AArch64::BI__builtin_neon_vld3q_dup_v: +      case AArch64::BI__builtin_neon_vld4_dup_v: +      case AArch64::BI__builtin_neon_vld4q_dup_v: +      case AArch64::BI__builtin_neon_vld2_lane_v: +      case AArch64::BI__builtin_neon_vld2q_lane_v: +        // Get the alignment for the argument in addition to the value; +        // we'll use it later. +        std::pair<llvm::Value *, unsigned> Src = +            EmitPointerWithAlignment(E->getArg(1)); +        Ops.push_back(Src.first); +        Align = Builder.getInt32(Src.second); +        continue; +      } +    } +    Ops.push_back(EmitScalarExpr(E->getArg(i))); +  } + +  // Get the last argument, which specifies the vector type. +  llvm::APSInt Result; +  const Expr *Arg = E->getArg(E->getNumArgs() - 1); +  if (!Arg->isIntegerConstantExpr(Result, getContext())) +    return 0; + +  // Determine the type of this overloaded NEON intrinsic. +  NeonTypeFlags Type(Result.getZExtValue()); +  bool usgn = Type.isUnsigned(); +  bool quad = Type.isQuad(); + +  llvm::VectorType *VTy = GetNeonType(this, Type); +  llvm::Type *Ty = VTy; +  if (!Ty) +    return 0; + +  unsigned Int; +  switch (BuiltinID) { +  default: +    return 0; + +  // AArch64 builtins mapping to legacy ARM v7 builtins. +  // FIXME: the mapped builtins listed correspond to what has been tested +  // in aarch64-neon-intrinsics.c so far. +  case AArch64::BI__builtin_neon_vuzp_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vuzp_v, E); +  case AArch64::BI__builtin_neon_vuzpq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vuzpq_v, E); +  case AArch64::BI__builtin_neon_vzip_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vzip_v, E); +  case AArch64::BI__builtin_neon_vzipq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vzipq_v, E); +  case AArch64::BI__builtin_neon_vtrn_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vtrn_v, E); +  case AArch64::BI__builtin_neon_vtrnq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vtrnq_v, E); +  case AArch64::BI__builtin_neon_vext_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vext_v, E); +  case AArch64::BI__builtin_neon_vextq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vextq_v, E); +  case AArch64::BI__builtin_neon_vmul_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmul_v, E); +  case AArch64::BI__builtin_neon_vmulq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmulq_v, E); +  case AArch64::BI__builtin_neon_vabd_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vabd_v, E); +  case AArch64::BI__builtin_neon_vabdq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vabdq_v, E); +  case AArch64::BI__builtin_neon_vfma_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vfma_v, E); +  case AArch64::BI__builtin_neon_vfmaq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vfmaq_v, E); +  case AArch64::BI__builtin_neon_vbsl_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vbsl_v, E); +  case AArch64::BI__builtin_neon_vbslq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vbslq_v, E); +  case AArch64::BI__builtin_neon_vrsqrts_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrsqrts_v, E); +  case AArch64::BI__builtin_neon_vrsqrtsq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrsqrtsq_v, E); +  case AArch64::BI__builtin_neon_vrecps_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrecps_v, E); +  case AArch64::BI__builtin_neon_vrecpsq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrecpsq_v, E); +  case AArch64::BI__builtin_neon_vcale_v: +    if (VTy->getVectorNumElements() == 1) { +      std::swap(Ops[0], Ops[1]); +    } else { +      return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcale_v, E); +    } +  case AArch64::BI__builtin_neon_vcage_v: +    if (VTy->getVectorNumElements() == 1) { +      // Determine the types of this overloaded AArch64 intrinsic +      SmallVector<llvm::Type *, 3> Tys; +      Tys.push_back(VTy); +      VTy = llvm::VectorType::get(DoubleTy, 1); +      Tys.push_back(VTy); +      Tys.push_back(VTy); +      Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_vcage, Tys); +      return EmitNeonCall(F, Ops, "vcage"); +    } +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcage_v, E); +  case AArch64::BI__builtin_neon_vcaleq_v: +    std::swap(Ops[0], Ops[1]); +  case AArch64::BI__builtin_neon_vcageq_v: { +    Function *F; +    if (VTy->getElementType()->isIntegerTy(64)) +      F = CGM.getIntrinsic(Intrinsic::aarch64_neon_vacgeq); +    else +      F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgeq); +    return EmitNeonCall(F, Ops, "vcage"); +  } +  case AArch64::BI__builtin_neon_vcalt_v: +    if (VTy->getVectorNumElements() == 1) { +      std::swap(Ops[0], Ops[1]); +    } else { +      return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcalt_v, E); +    } +  case AArch64::BI__builtin_neon_vcagt_v: +    if (VTy->getVectorNumElements() == 1) { +      // Determine the types of this overloaded AArch64 intrinsic +      SmallVector<llvm::Type *, 3> Tys; +      Tys.push_back(VTy); +      VTy = llvm::VectorType::get(DoubleTy, 1); +      Tys.push_back(VTy); +      Tys.push_back(VTy); +      Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_vcagt, Tys); +      return EmitNeonCall(F, Ops, "vcagt"); +    } +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcagt_v, E); +  case AArch64::BI__builtin_neon_vcaltq_v: +    std::swap(Ops[0], Ops[1]); +  case AArch64::BI__builtin_neon_vcagtq_v: { +    Function *F; +    if (VTy->getElementType()->isIntegerTy(64)) +      F = CGM.getIntrinsic(Intrinsic::aarch64_neon_vacgtq); +    else +      F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtq); +    return EmitNeonCall(F, Ops, "vcagt"); +  } +  case AArch64::BI__builtin_neon_vtst_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vtst_v, E); +  case AArch64::BI__builtin_neon_vtstq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vtstq_v, E); +  case AArch64::BI__builtin_neon_vhadd_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhadd_v, E); +  case AArch64::BI__builtin_neon_vhaddq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhaddq_v, E); +  case AArch64::BI__builtin_neon_vhsub_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhsub_v, E); +  case AArch64::BI__builtin_neon_vhsubq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhsubq_v, E); +  case AArch64::BI__builtin_neon_vrhadd_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrhadd_v, E); +  case AArch64::BI__builtin_neon_vrhaddq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrhaddq_v, E); +  case AArch64::BI__builtin_neon_vqadd_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqadd_v, E); +  case AArch64::BI__builtin_neon_vqaddq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqaddq_v, E); +  case AArch64::BI__builtin_neon_vqsub_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqsub_v, E); +  case AArch64::BI__builtin_neon_vqsubq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqsubq_v, E); +  case AArch64::BI__builtin_neon_vshl_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshl_v, E); +  case AArch64::BI__builtin_neon_vshlq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshlq_v, E); +  case AArch64::BI__builtin_neon_vqshl_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqshl_v, E); +  case AArch64::BI__builtin_neon_vqshlq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqshlq_v, E); +  case AArch64::BI__builtin_neon_vrshl_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrshl_v, E); +  case AArch64::BI__builtin_neon_vrshlq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrshlq_v, E); +  case AArch64::BI__builtin_neon_vqrshl_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrshl_v, E); +  case AArch64::BI__builtin_neon_vqrshlq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrshlq_v, E); +  case AArch64::BI__builtin_neon_vaddhn_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vaddhn_v, E); +  case AArch64::BI__builtin_neon_vraddhn_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vraddhn_v, E); +  case AArch64::BI__builtin_neon_vsubhn_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vsubhn_v, E); +  case AArch64::BI__builtin_neon_vrsubhn_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrsubhn_v, E); +  case AArch64::BI__builtin_neon_vmull_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmull_v, E); +  case AArch64::BI__builtin_neon_vqdmull_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmull_v, E); +  case AArch64::BI__builtin_neon_vqdmlal_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmlal_v, E); +  case AArch64::BI__builtin_neon_vqdmlsl_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmlsl_v, E); +  case AArch64::BI__builtin_neon_vmax_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmax_v, E); +  case AArch64::BI__builtin_neon_vmaxq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmaxq_v, E); +  case AArch64::BI__builtin_neon_vmin_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmin_v, E); +  case AArch64::BI__builtin_neon_vminq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vminq_v, E); +  case AArch64::BI__builtin_neon_vpmax_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpmax_v, E); +  case AArch64::BI__builtin_neon_vpmin_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpmin_v, E); +  case AArch64::BI__builtin_neon_vpadd_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpadd_v, E); +  case AArch64::BI__builtin_neon_vqdmulh_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmulh_v, E); +  case AArch64::BI__builtin_neon_vqdmulhq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmulhq_v, E); +  case AArch64::BI__builtin_neon_vqrdmulh_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrdmulh_v, E); +  case AArch64::BI__builtin_neon_vqrdmulhq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrdmulhq_v, E); + +  // Shift by immediate +  case AArch64::BI__builtin_neon_vshr_n_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshr_n_v, E); +  case AArch64::BI__builtin_neon_vshrq_n_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshrq_n_v, E); +  case AArch64::BI__builtin_neon_vrshr_n_v: +  case AArch64::BI__builtin_neon_vrshrq_n_v: +    Int = usgn ? Intrinsic::aarch64_neon_vurshr +               : Intrinsic::aarch64_neon_vsrshr; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n"); +  case AArch64::BI__builtin_neon_vsra_n_v: +    if (VTy->getElementType()->isIntegerTy(64)) { +      Int = usgn ? Intrinsic::aarch64_neon_vsradu_n +                 : Intrinsic::aarch64_neon_vsrads_n; +      return EmitNeonCall(CGM.getIntrinsic(Int), Ops, "vsra_n"); +    } +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vsra_n_v, E); +  case AArch64::BI__builtin_neon_vsraq_n_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vsraq_n_v, E); +  case AArch64::BI__builtin_neon_vrsra_n_v: +    if (VTy->getElementType()->isIntegerTy(64)) { +      Int = usgn ? Intrinsic::aarch64_neon_vrsradu_n +                 : Intrinsic::aarch64_neon_vrsrads_n; +      return EmitNeonCall(CGM.getIntrinsic(Int), Ops, "vrsra_n"); +    } +    // fall through +  case AArch64::BI__builtin_neon_vrsraq_n_v: { +    Ops[0] = Builder.CreateBitCast(Ops[0], Ty); +    Ops[1] = Builder.CreateBitCast(Ops[1], Ty); +    Int = usgn ? Intrinsic::aarch64_neon_vurshr +               : Intrinsic::aarch64_neon_vsrshr; +    Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, Ty), Ops[1], Ops[2]); +    return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); +  } +  case AArch64::BI__builtin_neon_vshl_n_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshl_n_v, E); +  case AArch64::BI__builtin_neon_vshlq_n_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshlq_n_v, E); +  case AArch64::BI__builtin_neon_vqshl_n_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqshl_n_v, E); +  case AArch64::BI__builtin_neon_vqshlq_n_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqshlq_n_v, E); +  case AArch64::BI__builtin_neon_vqshlu_n_v: +  case AArch64::BI__builtin_neon_vqshluq_n_v: +    Int = Intrinsic::aarch64_neon_vsqshlu; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n"); +  case AArch64::BI__builtin_neon_vsri_n_v: +  case AArch64::BI__builtin_neon_vsriq_n_v: +    Int = Intrinsic::aarch64_neon_vsri; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsri_n"); +  case AArch64::BI__builtin_neon_vsli_n_v: +  case AArch64::BI__builtin_neon_vsliq_n_v: +    Int = Intrinsic::aarch64_neon_vsli; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsli_n"); +  case AArch64::BI__builtin_neon_vshll_n_v: { +    llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy); +    Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); +    if (usgn) +      Ops[0] = Builder.CreateZExt(Ops[0], VTy); +    else +      Ops[0] = Builder.CreateSExt(Ops[0], VTy); +    Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false); +    return Builder.CreateShl(Ops[0], Ops[1], "vshll_n"); +  } +  case AArch64::BI__builtin_neon_vshrn_n_v: { +    llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy); +    Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); +    Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false); +    if (usgn) +      Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]); +    else +      Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]); +    return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n"); +  } +  case AArch64::BI__builtin_neon_vqshrun_n_v: +    Int = Intrinsic::aarch64_neon_vsqshrun; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n"); +  case AArch64::BI__builtin_neon_vrshrn_n_v: +    Int = Intrinsic::aarch64_neon_vrshrn; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n"); +  case AArch64::BI__builtin_neon_vqrshrun_n_v: +    Int = Intrinsic::aarch64_neon_vsqrshrun; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n"); +  case AArch64::BI__builtin_neon_vqshrn_n_v: +    Int = usgn ? Intrinsic::aarch64_neon_vuqshrn +               : Intrinsic::aarch64_neon_vsqshrn; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n"); +  case AArch64::BI__builtin_neon_vqrshrn_n_v: +    Int = usgn ? Intrinsic::aarch64_neon_vuqrshrn +               : Intrinsic::aarch64_neon_vsqrshrn; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n"); + +  // Convert +  case AArch64::BI__builtin_neon_vmovl_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmovl_v, E); +  case AArch64::BI__builtin_neon_vcvt_n_f32_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_n_f32_v, E); +  case AArch64::BI__builtin_neon_vcvtq_n_f32_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvtq_n_f32_v, E); +  case AArch64::BI__builtin_neon_vcvt_n_f64_v: +  case AArch64::BI__builtin_neon_vcvtq_n_f64_v: { +    llvm::Type *FloatTy = +        GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad)); +    llvm::Type *Tys[2] = { FloatTy, Ty }; +    Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp +               : Intrinsic::arm_neon_vcvtfxs2fp; +    Function *F = CGM.getIntrinsic(Int, Tys); +    return EmitNeonCall(F, Ops, "vcvt_n"); +  } +  case AArch64::BI__builtin_neon_vcvt_n_s32_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_n_s32_v, E); +  case AArch64::BI__builtin_neon_vcvtq_n_s32_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvtq_n_s32_v, E); +  case AArch64::BI__builtin_neon_vcvt_n_u32_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_n_u32_v, E); +  case AArch64::BI__builtin_neon_vcvtq_n_u32_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvtq_n_u32_v, E); +  case AArch64::BI__builtin_neon_vcvt_n_s64_v: +  case AArch64::BI__builtin_neon_vcvt_n_u64_v: +  case AArch64::BI__builtin_neon_vcvtq_n_s64_v: +  case AArch64::BI__builtin_neon_vcvtq_n_u64_v: { +    llvm::Type *FloatTy = +        GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad)); +    llvm::Type *Tys[2] = { Ty, FloatTy }; +    Int = usgn ? Intrinsic::arm_neon_vcvtfp2fxu +               : Intrinsic::arm_neon_vcvtfp2fxs; +    Function *F = CGM.getIntrinsic(Int, Tys); +    return EmitNeonCall(F, Ops, "vcvt_n"); +  } + +  // Load/Store +  case AArch64::BI__builtin_neon_vld1_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld1_v, E); +  case AArch64::BI__builtin_neon_vld1q_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld1q_v, E); +  case AArch64::BI__builtin_neon_vld2_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld2_v, E); +  case AArch64::BI__builtin_neon_vld2q_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld2q_v, E); +  case AArch64::BI__builtin_neon_vld3_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld3_v, E); +  case AArch64::BI__builtin_neon_vld3q_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld3q_v, E); +  case AArch64::BI__builtin_neon_vld4_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld4_v, E); +  case AArch64::BI__builtin_neon_vld4q_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld4q_v, E); +  case AArch64::BI__builtin_neon_vst1_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst1_v, E); +  case AArch64::BI__builtin_neon_vst1q_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst1q_v, E); +  case AArch64::BI__builtin_neon_vst2_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst2_v, E); +  case AArch64::BI__builtin_neon_vst2q_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst2q_v, E); +  case AArch64::BI__builtin_neon_vst3_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst3_v, E); +  case AArch64::BI__builtin_neon_vst3q_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst3q_v, E); +  case AArch64::BI__builtin_neon_vst4_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst4_v, E); +  case AArch64::BI__builtin_neon_vst4q_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst4q_v, E); +  case AArch64::BI__builtin_neon_vld1_x2_v: +  case AArch64::BI__builtin_neon_vld1q_x2_v: +  case AArch64::BI__builtin_neon_vld1_x3_v: +  case AArch64::BI__builtin_neon_vld1q_x3_v: +  case AArch64::BI__builtin_neon_vld1_x4_v: +  case AArch64::BI__builtin_neon_vld1q_x4_v: { +    unsigned Int; +    switch (BuiltinID) { +    case AArch64::BI__builtin_neon_vld1_x2_v: +    case AArch64::BI__builtin_neon_vld1q_x2_v: +      Int = Intrinsic::aarch64_neon_vld1x2; +      break; +    case AArch64::BI__builtin_neon_vld1_x3_v: +    case AArch64::BI__builtin_neon_vld1q_x3_v: +      Int = Intrinsic::aarch64_neon_vld1x3; +      break; +    case AArch64::BI__builtin_neon_vld1_x4_v: +    case AArch64::BI__builtin_neon_vld1q_x4_v: +      Int = Intrinsic::aarch64_neon_vld1x4; +      break; +    } +    Function *F = CGM.getIntrinsic(Int, Ty); +    Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld1xN"); +    Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); +    Ops[0] = Builder.CreateBitCast(Ops[0], Ty); +    return Builder.CreateStore(Ops[1], Ops[0]); +  } +  case AArch64::BI__builtin_neon_vst1_x2_v: +  case AArch64::BI__builtin_neon_vst1q_x2_v: +  case AArch64::BI__builtin_neon_vst1_x3_v: +  case AArch64::BI__builtin_neon_vst1q_x3_v: +  case AArch64::BI__builtin_neon_vst1_x4_v: +  case AArch64::BI__builtin_neon_vst1q_x4_v: { +    Ops.push_back(Align); +    unsigned Int; +    switch (BuiltinID) { +    case AArch64::BI__builtin_neon_vst1_x2_v: +    case AArch64::BI__builtin_neon_vst1q_x2_v: +      Int = Intrinsic::aarch64_neon_vst1x2; +      break; +    case AArch64::BI__builtin_neon_vst1_x3_v: +    case AArch64::BI__builtin_neon_vst1q_x3_v: +      Int = Intrinsic::aarch64_neon_vst1x3; +      break; +    case AArch64::BI__builtin_neon_vst1_x4_v: +    case AArch64::BI__builtin_neon_vst1q_x4_v: +      Int = Intrinsic::aarch64_neon_vst1x4; +      break; +    } +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, ""); +  } +  case AArch64::BI__builtin_neon_vld1_lane_v: +  case AArch64::BI__builtin_neon_vld1q_lane_v: { +    Ops[1] = Builder.CreateBitCast(Ops[1], Ty); +    Ty = llvm::PointerType::getUnqual(VTy->getElementType()); +    Ops[0] = Builder.CreateBitCast(Ops[0], Ty); +    LoadInst *Ld = Builder.CreateLoad(Ops[0]); +    Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); +    return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane"); +  } +  case AArch64::BI__builtin_neon_vld2_lane_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld2q_lane_v, E); +  case AArch64::BI__builtin_neon_vld2q_lane_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld2q_lane_v, E); +  case AArch64::BI__builtin_neon_vld3_lane_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld3_lane_v, E); +  case AArch64::BI__builtin_neon_vld3q_lane_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld3q_lane_v, E); +  case AArch64::BI__builtin_neon_vld4_lane_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld4_lane_v, E); +  case AArch64::BI__builtin_neon_vld4q_lane_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld4q_lane_v, E); +  case AArch64::BI__builtin_neon_vst1_lane_v: +  case AArch64::BI__builtin_neon_vst1q_lane_v: { +    Ops[1] = Builder.CreateBitCast(Ops[1], Ty); +    Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); +    Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); +    StoreInst *St = +        Builder.CreateStore(Ops[1], Builder.CreateBitCast(Ops[0], Ty)); +    St->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); +    return St; +  } +  case AArch64::BI__builtin_neon_vst2_lane_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst2_lane_v, E); +  case AArch64::BI__builtin_neon_vst2q_lane_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst2q_lane_v, E); +  case AArch64::BI__builtin_neon_vst3_lane_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst3_lane_v, E); +  case AArch64::BI__builtin_neon_vst3q_lane_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst3q_lane_v, E); +  case AArch64::BI__builtin_neon_vst4_lane_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst4_lane_v, E); +  case AArch64::BI__builtin_neon_vst4q_lane_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst4q_lane_v, E); +  case AArch64::BI__builtin_neon_vld1_dup_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld1_dup_v, E); +  case AArch64::BI__builtin_neon_vld1q_dup_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld1q_dup_v, E); +  case AArch64::BI__builtin_neon_vld2_dup_v: +  case AArch64::BI__builtin_neon_vld2q_dup_v: +  case AArch64::BI__builtin_neon_vld3_dup_v: +  case AArch64::BI__builtin_neon_vld3q_dup_v: +  case AArch64::BI__builtin_neon_vld4_dup_v: +  case AArch64::BI__builtin_neon_vld4q_dup_v: { +    // Handle 64-bit x 1 elements as a special-case.  There is no "dup" needed. +    if (VTy->getElementType()->getPrimitiveSizeInBits() == 64 && +        VTy->getNumElements() == 1) { +      switch (BuiltinID) { +      case AArch64::BI__builtin_neon_vld2_dup_v: +        Int = Intrinsic::arm_neon_vld2; +        break; +      case AArch64::BI__builtin_neon_vld3_dup_v: +        Int = Intrinsic::arm_neon_vld3; +        break; +      case AArch64::BI__builtin_neon_vld4_dup_v: +        Int = Intrinsic::arm_neon_vld4; +        break; +      default: +        llvm_unreachable("unknown vld_dup intrinsic?"); +      } +      Function *F = CGM.getIntrinsic(Int, Ty); +      Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld_dup"); +      Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); +      Ops[0] = Builder.CreateBitCast(Ops[0], Ty); +      return Builder.CreateStore(Ops[1], Ops[0]); +    } +    switch (BuiltinID) { +    case AArch64::BI__builtin_neon_vld2_dup_v: +    case AArch64::BI__builtin_neon_vld2q_dup_v: +      Int = Intrinsic::arm_neon_vld2lane; +      break; +    case AArch64::BI__builtin_neon_vld3_dup_v: +    case AArch64::BI__builtin_neon_vld3q_dup_v: +      Int = Intrinsic::arm_neon_vld3lane; +      break; +    case AArch64::BI__builtin_neon_vld4_dup_v: +    case AArch64::BI__builtin_neon_vld4q_dup_v: +      Int = Intrinsic::arm_neon_vld4lane; +      break; +    } +    Function *F = CGM.getIntrinsic(Int, Ty); +    llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); + +    SmallVector<Value *, 6> Args; +    Args.push_back(Ops[1]); +    Args.append(STy->getNumElements(), UndefValue::get(Ty)); + +    llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); +    Args.push_back(CI); +    Args.push_back(Align); + +    Ops[1] = Builder.CreateCall(F, Args, "vld_dup"); +    // splat lane 0 to all elts in each vector of the result. +    for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { +      Value *Val = Builder.CreateExtractValue(Ops[1], i); +      Value *Elt = Builder.CreateBitCast(Val, Ty); +      Elt = EmitNeonSplat(Elt, CI); +      Elt = Builder.CreateBitCast(Elt, Val->getType()); +      Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); +    } +    Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); +    Ops[0] = Builder.CreateBitCast(Ops[0], Ty); +    return Builder.CreateStore(Ops[1], Ops[0]); +  } + +  // Crypto +  case AArch64::BI__builtin_neon_vaeseq_v: +    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_aese, Ty), +                        Ops, "aese"); +  case AArch64::BI__builtin_neon_vaesdq_v: +    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_aesd, Ty), +                        Ops, "aesd"); +  case AArch64::BI__builtin_neon_vaesmcq_v: +    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_aesmc, Ty), +                        Ops, "aesmc"); +  case AArch64::BI__builtin_neon_vaesimcq_v: +    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_aesimc, Ty), +                        Ops, "aesimc"); +  case AArch64::BI__builtin_neon_vsha1su1q_v: +    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1su1, Ty), +                        Ops, "sha1su1"); +  case AArch64::BI__builtin_neon_vsha256su0q_v: +    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha256su0, Ty), +                        Ops, "sha256su0"); +  case AArch64::BI__builtin_neon_vsha1su0q_v: +    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1su0, Ty), +                        Ops, "sha1su0"); +  case AArch64::BI__builtin_neon_vsha256hq_v: +    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha256h, Ty), +                        Ops, "sha256h"); +  case AArch64::BI__builtin_neon_vsha256h2q_v: +    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha256h2, Ty), +                        Ops, "sha256h2"); +  case AArch64::BI__builtin_neon_vsha256su1q_v: +    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha256su1, Ty), +                        Ops, "sha256su1"); +  case AArch64::BI__builtin_neon_vmul_lane_v: +  case AArch64::BI__builtin_neon_vmul_laneq_v: { +    // v1f64 vmul_lane should be mapped to Neon scalar mul lane +    bool Quad = false; +    if (BuiltinID == AArch64::BI__builtin_neon_vmul_laneq_v) +      Quad = true; +    Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); +    llvm::Type *VTy = GetNeonType(this, +      NeonTypeFlags(NeonTypeFlags::Float64, false, Quad)); +    Ops[1] = Builder.CreateBitCast(Ops[1], VTy); +    Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract"); +    Value *Result = Builder.CreateFMul(Ops[0], Ops[1]); +    return Builder.CreateBitCast(Result, Ty); +  } + +  // AArch64-only builtins +  case AArch64::BI__builtin_neon_vfmaq_laneq_v: { +    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); +    Ops[0] = Builder.CreateBitCast(Ops[0], Ty); +    Ops[1] = Builder.CreateBitCast(Ops[1], Ty); + +    Ops[2] = Builder.CreateBitCast(Ops[2], Ty); +    Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3])); +    return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]); +  } +  case AArch64::BI__builtin_neon_vfmaq_lane_v: { +    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); +    Ops[0] = Builder.CreateBitCast(Ops[0], Ty); +    Ops[1] = Builder.CreateBitCast(Ops[1], Ty); + +    llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); +    llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(), +                                            VTy->getNumElements() / 2); +    Ops[2] = Builder.CreateBitCast(Ops[2], STy); +    Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), +                                               cast<ConstantInt>(Ops[3])); +    Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane"); + +    return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]); +  } +  case AArch64::BI__builtin_neon_vfma_lane_v: { +    llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); +    // v1f64 fma should be mapped to Neon scalar f64 fma +    if (VTy && VTy->getElementType() == DoubleTy) { +      Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); +      Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); +      llvm::Type *VTy = GetNeonType(this, +        NeonTypeFlags(NeonTypeFlags::Float64, false, false)); +      Ops[2] = Builder.CreateBitCast(Ops[2], VTy); +      Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); +      Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy); +      Value *Result = Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); +      return Builder.CreateBitCast(Result, Ty); +    } +    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); +    Ops[0] = Builder.CreateBitCast(Ops[0], Ty); +    Ops[1] = Builder.CreateBitCast(Ops[1], Ty); + +    Ops[2] = Builder.CreateBitCast(Ops[2], Ty); +    Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3])); +    return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]); +  } +  case AArch64::BI__builtin_neon_vfma_laneq_v: { +    llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); +    // v1f64 fma should be mapped to Neon scalar f64 fma +    if (VTy && VTy->getElementType() == DoubleTy) { +      Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); +      Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); +      llvm::Type *VTy = GetNeonType(this, +        NeonTypeFlags(NeonTypeFlags::Float64, false, true)); +      Ops[2] = Builder.CreateBitCast(Ops[2], VTy); +      Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); +      Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy); +      Value *Result = Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); +      return Builder.CreateBitCast(Result, Ty); +    } +    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); +    Ops[0] = Builder.CreateBitCast(Ops[0], Ty); +    Ops[1] = Builder.CreateBitCast(Ops[1], Ty); + +    llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(), +                                            VTy->getNumElements() * 2); +    Ops[2] = Builder.CreateBitCast(Ops[2], STy); +    Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), +                                               cast<ConstantInt>(Ops[3])); +    Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane"); + +    return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]); +  } +  case AArch64::BI__builtin_neon_vfms_v: +  case AArch64::BI__builtin_neon_vfmsq_v: { +    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); +    Ops[0] = Builder.CreateBitCast(Ops[0], Ty); +    Ops[1] = Builder.CreateBitCast(Ops[1], Ty); +    Ops[1] = Builder.CreateFNeg(Ops[1]); +    Ops[2] = Builder.CreateBitCast(Ops[2], Ty); + +    // LLVM's fma intrinsic puts the accumulator in the last position, but the +    // AArch64 intrinsic has it first. +    return Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); +  } +  case AArch64::BI__builtin_neon_vmaxnm_v: +  case AArch64::BI__builtin_neon_vmaxnmq_v: { +    Int = Intrinsic::aarch64_neon_vmaxnm; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm"); +  } +  case AArch64::BI__builtin_neon_vminnm_v: +  case AArch64::BI__builtin_neon_vminnmq_v: { +    Int = Intrinsic::aarch64_neon_vminnm; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm"); +  } +  case AArch64::BI__builtin_neon_vpmaxnm_v: +  case AArch64::BI__builtin_neon_vpmaxnmq_v: { +    Int = Intrinsic::aarch64_neon_vpmaxnm; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm"); +  } +  case AArch64::BI__builtin_neon_vpminnm_v: +  case AArch64::BI__builtin_neon_vpminnmq_v: { +    Int = Intrinsic::aarch64_neon_vpminnm; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm"); +  } +  case AArch64::BI__builtin_neon_vpmaxq_v: { +    Int = usgn ? Intrinsic::arm_neon_vpmaxu : Intrinsic::arm_neon_vpmaxs; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax"); +  } +  case AArch64::BI__builtin_neon_vpminq_v: { +    Int = usgn ? Intrinsic::arm_neon_vpminu : Intrinsic::arm_neon_vpmins; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin"); +  } +  case AArch64::BI__builtin_neon_vpaddq_v: { +    Int = Intrinsic::arm_neon_vpadd; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpadd"); +  } +  case AArch64::BI__builtin_neon_vmulx_v: +  case AArch64::BI__builtin_neon_vmulxq_v: { +    Int = Intrinsic::aarch64_neon_vmulx; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx"); +  } +  case AArch64::BI__builtin_neon_vpaddl_v: +  case AArch64::BI__builtin_neon_vpaddlq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpaddl_v, E); +  case AArch64::BI__builtin_neon_vpadal_v: +  case AArch64::BI__builtin_neon_vpadalq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpadal_v, E); +  case AArch64::BI__builtin_neon_vqabs_v: +  case AArch64::BI__builtin_neon_vqabsq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqabs_v, E); +  case AArch64::BI__builtin_neon_vqneg_v: +  case AArch64::BI__builtin_neon_vqnegq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqneg_v, E); +  case AArch64::BI__builtin_neon_vabs_v: +  case AArch64::BI__builtin_neon_vabsq_v: { +    if (VTy->getElementType()->isFloatingPointTy()) { +      return EmitNeonCall(CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops, "vabs"); +    } +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vabs_v, E); +  } +  case AArch64::BI__builtin_neon_vsqadd_v: +  case AArch64::BI__builtin_neon_vsqaddq_v: { +    Int = Intrinsic::aarch64_neon_usqadd; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqadd"); +  } +  case AArch64::BI__builtin_neon_vuqadd_v: +  case AArch64::BI__builtin_neon_vuqaddq_v: { +    Int = Intrinsic::aarch64_neon_suqadd; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd"); +  } +  case AArch64::BI__builtin_neon_vcls_v: +  case AArch64::BI__builtin_neon_vclsq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcls_v, E); +  case AArch64::BI__builtin_neon_vclz_v: +  case AArch64::BI__builtin_neon_vclzq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vclz_v, E); +  case AArch64::BI__builtin_neon_vcnt_v: +  case AArch64::BI__builtin_neon_vcntq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcnt_v, E); +  case AArch64::BI__builtin_neon_vrbit_v: +  case AArch64::BI__builtin_neon_vrbitq_v: +    Int = Intrinsic::aarch64_neon_rbit; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrbit"); +  case AArch64::BI__builtin_neon_vmovn_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmovn_v, E); +  case AArch64::BI__builtin_neon_vqmovun_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqmovun_v, E); +  case AArch64::BI__builtin_neon_vqmovn_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqmovn_v, E); +  case AArch64::BI__builtin_neon_vcvt_f16_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_f16_v, E); +  case AArch64::BI__builtin_neon_vcvt_f32_f16: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_f32_f16, E); +  case AArch64::BI__builtin_neon_vcvt_f32_f64: { +    Ops[0] = Builder.CreateBitCast(Ops[0], Ty); +    Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, false)); +    return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt"); +  } +  case AArch64::BI__builtin_neon_vcvtx_f32_v: { +    llvm::Type *EltTy = FloatTy; +    llvm::Type *ResTy = llvm::VectorType::get(EltTy, 2); +    llvm::Type *Tys[2] = { ResTy, Ty }; +    Int = Intrinsic::aarch64_neon_fcvtxn; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtx_f32_f64"); +  } +  case AArch64::BI__builtin_neon_vcvt_f64_f32: { +    llvm::Type *OpTy = +        GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, false)); +    Ops[0] = Builder.CreateBitCast(Ops[0], OpTy); +    return Builder.CreateFPExt(Ops[0], Ty, "vcvt"); +  } +  case AArch64::BI__builtin_neon_vcvt_f64_v: +  case AArch64::BI__builtin_neon_vcvtq_f64_v: { +    Ops[0] = Builder.CreateBitCast(Ops[0], Ty); +    Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad)); +    return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") +                : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); +  } +  case AArch64::BI__builtin_neon_vrndn_v: +  case AArch64::BI__builtin_neon_vrndnq_v: { +    Int = Intrinsic::aarch64_neon_frintn; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn"); +  } +  case AArch64::BI__builtin_neon_vrnda_v: +  case AArch64::BI__builtin_neon_vrndaq_v: { +    Int = Intrinsic::round; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnda"); +  } +  case AArch64::BI__builtin_neon_vrndp_v: +  case AArch64::BI__builtin_neon_vrndpq_v: { +    Int = Intrinsic::ceil; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndp"); +  } +  case AArch64::BI__builtin_neon_vrndm_v: +  case AArch64::BI__builtin_neon_vrndmq_v: { +    Int = Intrinsic::floor; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndm"); +  } +  case AArch64::BI__builtin_neon_vrndx_v: +  case AArch64::BI__builtin_neon_vrndxq_v: { +    Int = Intrinsic::rint; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndx"); +  } +  case AArch64::BI__builtin_neon_vrnd_v: +  case AArch64::BI__builtin_neon_vrndq_v: { +    Int = Intrinsic::trunc; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnd"); +  } +  case AArch64::BI__builtin_neon_vrndi_v: +  case AArch64::BI__builtin_neon_vrndiq_v: { +    Int = Intrinsic::nearbyint; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndi"); +  } +  case AArch64::BI__builtin_neon_vcvt_s32_v: +  case AArch64::BI__builtin_neon_vcvt_u32_v: +  case AArch64::BI__builtin_neon_vcvtq_s32_v: +  case AArch64::BI__builtin_neon_vcvtq_u32_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvtq_u32_v, E); +  case AArch64::BI__builtin_neon_vcvt_s64_v: +  case AArch64::BI__builtin_neon_vcvt_u64_v: +  case AArch64::BI__builtin_neon_vcvtq_s64_v: +  case AArch64::BI__builtin_neon_vcvtq_u64_v: { +    llvm::Type *DoubleTy = +        GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad)); +    Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); +    return usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") +                : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); +  } +  case AArch64::BI__builtin_neon_vcvtn_s32_v: +  case AArch64::BI__builtin_neon_vcvtnq_s32_v: { +    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtns; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtns_f32"); +  } +  case AArch64::BI__builtin_neon_vcvtn_s64_v: +  case AArch64::BI__builtin_neon_vcvtnq_s64_v: { +    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtns; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtns_f64"); +  } +  case AArch64::BI__builtin_neon_vcvtn_u32_v: +  case AArch64::BI__builtin_neon_vcvtnq_u32_v: { +    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtnu; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtnu_f32"); +  } +  case AArch64::BI__builtin_neon_vcvtn_u64_v: +  case AArch64::BI__builtin_neon_vcvtnq_u64_v: { +    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtnu; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtnu_f64"); +  } +  case AArch64::BI__builtin_neon_vcvtp_s32_v: +  case AArch64::BI__builtin_neon_vcvtpq_s32_v: { +    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtps; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtps_f32"); +  } +  case AArch64::BI__builtin_neon_vcvtp_s64_v: +  case AArch64::BI__builtin_neon_vcvtpq_s64_v: { +    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtps; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtps_f64"); +  } +  case AArch64::BI__builtin_neon_vcvtp_u32_v: +  case AArch64::BI__builtin_neon_vcvtpq_u32_v: { +    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtpu; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtpu_f32"); +  } +  case AArch64::BI__builtin_neon_vcvtp_u64_v: +  case AArch64::BI__builtin_neon_vcvtpq_u64_v: { +    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtpu; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtpu_f64"); +  } +  case AArch64::BI__builtin_neon_vcvtm_s32_v: +  case AArch64::BI__builtin_neon_vcvtmq_s32_v: { +    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtms; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtms_f32"); +  } +  case AArch64::BI__builtin_neon_vcvtm_s64_v: +  case AArch64::BI__builtin_neon_vcvtmq_s64_v: { +    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtms; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtms_f64"); +  } +  case AArch64::BI__builtin_neon_vcvtm_u32_v: +  case AArch64::BI__builtin_neon_vcvtmq_u32_v: { +    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtmu; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtmu_f32"); +  } +  case AArch64::BI__builtin_neon_vcvtm_u64_v: +  case AArch64::BI__builtin_neon_vcvtmq_u64_v: { +    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtmu; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtmu_f64"); +  } +  case AArch64::BI__builtin_neon_vcvta_s32_v: +  case AArch64::BI__builtin_neon_vcvtaq_s32_v: { +    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtas; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtas_f32"); +  } +  case AArch64::BI__builtin_neon_vcvta_s64_v: +  case AArch64::BI__builtin_neon_vcvtaq_s64_v: { +    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtas; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtas_f64"); +  } +  case AArch64::BI__builtin_neon_vcvta_u32_v: +  case AArch64::BI__builtin_neon_vcvtaq_u32_v: { +    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtau; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtau_f32"); +  } +  case AArch64::BI__builtin_neon_vcvta_u64_v: +  case AArch64::BI__builtin_neon_vcvtaq_u64_v: { +    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements()); +    llvm::Type *Tys[2] = { Ty, OpTy }; +    Int = Intrinsic::aarch64_neon_fcvtau; +    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtau_f64"); +  } +  case AArch64::BI__builtin_neon_vrecpe_v: +  case AArch64::BI__builtin_neon_vrecpeq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrecpe_v, E); +  case AArch64::BI__builtin_neon_vrsqrte_v: +  case AArch64::BI__builtin_neon_vrsqrteq_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrsqrte_v, E); +  case AArch64::BI__builtin_neon_vsqrt_v: +  case AArch64::BI__builtin_neon_vsqrtq_v: { +    Int = Intrinsic::sqrt; +    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqrt"); +  } +  case AArch64::BI__builtin_neon_vcvt_f32_v: +  case AArch64::BI__builtin_neon_vcvtq_f32_v: +    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_f32_v, E); +  case AArch64::BI__builtin_neon_vceqz_v: +  case AArch64::BI__builtin_neon_vceqzq_v: +    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OEQ, +                                         ICmpInst::ICMP_EQ, "vceqz"); +  case AArch64::BI__builtin_neon_vcgez_v: +  case AArch64::BI__builtin_neon_vcgezq_v: +    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGE, +                                         ICmpInst::ICMP_SGE, "vcgez"); +  case AArch64::BI__builtin_neon_vclez_v: +  case AArch64::BI__builtin_neon_vclezq_v: +    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLE, +                                         ICmpInst::ICMP_SLE, "vclez"); +  case AArch64::BI__builtin_neon_vcgtz_v: +  case AArch64::BI__builtin_neon_vcgtzq_v: +    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGT, +                                         ICmpInst::ICMP_SGT, "vcgtz"); +  case AArch64::BI__builtin_neon_vcltz_v: +  case AArch64::BI__builtin_neon_vcltzq_v: +    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLT, +                                         ICmpInst::ICMP_SLT, "vcltz"); +  }  }  Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,                                             const CallExpr *E) {    if (BuiltinID == ARM::BI__clear_cache) { +    assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");      const FunctionDecl *FD = E->getDirectCallee(); -    // Oddly people write this call without args on occasion and gcc accepts -    // it - it's also marked as varargs in the description file.      SmallVector<Value*, 2> Ops; -    for (unsigned i = 0; i < E->getNumArgs(); i++) +    for (unsigned i = 0; i < 2; i++)        Ops.push_back(EmitScalarExpr(E->getArg(i)));      llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());      llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); @@ -1657,11 +3937,14 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,      return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);    } -  if (BuiltinID == ARM::BI__builtin_arm_ldrexd) { +  if (BuiltinID == ARM::BI__builtin_arm_ldrexd || +      (BuiltinID == ARM::BI__builtin_arm_ldrex && +       getContext().getTypeSize(E->getType()) == 64)) {      Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrexd);      Value *LdPtr = EmitScalarExpr(E->getArg(0)); -    Value *Val = Builder.CreateCall(F, LdPtr, "ldrexd"); +    Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), +                                    "ldrexd");      Value *Val0 = Builder.CreateExtractValue(Val, 1);      Value *Val1 = Builder.CreateExtractValue(Val, 0); @@ -1670,15 +3953,37 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,      Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32);      Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); -    return Builder.CreateOr(Val, Val1); +    Val = Builder.CreateOr(Val, Val1); +    return Builder.CreateBitCast(Val, ConvertType(E->getType())); +  } + +  if (BuiltinID == ARM::BI__builtin_arm_ldrex) { +    Value *LoadAddr = EmitScalarExpr(E->getArg(0)); + +    QualType Ty = E->getType(); +    llvm::Type *RealResTy = ConvertType(Ty); +    llvm::Type *IntResTy = llvm::IntegerType::get(getLLVMContext(), +                                                  getContext().getTypeSize(Ty)); +    LoadAddr = Builder.CreateBitCast(LoadAddr, IntResTy->getPointerTo()); + +    Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrex, LoadAddr->getType()); +    Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex"); + +    if (RealResTy->isPointerTy()) +      return Builder.CreateIntToPtr(Val, RealResTy); +    else { +      Val = Builder.CreateTruncOrBitCast(Val, IntResTy); +      return Builder.CreateBitCast(Val, RealResTy); +    }    } -  if (BuiltinID == ARM::BI__builtin_arm_strexd) { +  if (BuiltinID == ARM::BI__builtin_arm_strexd || +      (BuiltinID == ARM::BI__builtin_arm_strex && +       getContext().getTypeSize(E->getArg(0)->getType()) == 64)) {      Function *F = CGM.getIntrinsic(Intrinsic::arm_strexd);      llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, NULL); -    Value *One = llvm::ConstantInt::get(Int32Ty, 1); -    Value *Tmp = Builder.CreateAlloca(Int64Ty, One); +    Value *Tmp = CreateMemTemp(E->getArg(0)->getType());      Value *Val = EmitScalarExpr(E->getArg(0));      Builder.CreateStore(Val, Tmp); @@ -1687,10 +3992,83 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,      Value *Arg0 = Builder.CreateExtractValue(Val, 0);      Value *Arg1 = Builder.CreateExtractValue(Val, 1); -    Value *StPtr = EmitScalarExpr(E->getArg(1)); +    Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), Int8PtrTy);      return Builder.CreateCall3(F, Arg0, Arg1, StPtr, "strexd");    } +  if (BuiltinID == ARM::BI__builtin_arm_strex) { +    Value *StoreVal = EmitScalarExpr(E->getArg(0)); +    Value *StoreAddr = EmitScalarExpr(E->getArg(1)); + +    QualType Ty = E->getArg(0)->getType(); +    llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), +                                                 getContext().getTypeSize(Ty)); +    StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); + +    if (StoreVal->getType()->isPointerTy()) +      StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty); +    else { +      StoreVal = Builder.CreateBitCast(StoreVal, StoreTy); +      StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty); +    } + +    Function *F = CGM.getIntrinsic(Intrinsic::arm_strex, StoreAddr->getType()); +    return Builder.CreateCall2(F, StoreVal, StoreAddr, "strex"); +  } + +  if (BuiltinID == ARM::BI__builtin_arm_clrex) { +    Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex); +    return Builder.CreateCall(F); +  } + +  if (BuiltinID == ARM::BI__builtin_arm_sevl) { +    Function *F = CGM.getIntrinsic(Intrinsic::arm_sevl); +    return Builder.CreateCall(F); +  } + +  // CRC32 +  Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; +  switch (BuiltinID) { +  case ARM::BI__builtin_arm_crc32b: +    CRCIntrinsicID = Intrinsic::arm_crc32b; break; +  case ARM::BI__builtin_arm_crc32cb: +    CRCIntrinsicID = Intrinsic::arm_crc32cb; break; +  case ARM::BI__builtin_arm_crc32h: +    CRCIntrinsicID = Intrinsic::arm_crc32h; break; +  case ARM::BI__builtin_arm_crc32ch: +    CRCIntrinsicID = Intrinsic::arm_crc32ch; break; +  case ARM::BI__builtin_arm_crc32w: +  case ARM::BI__builtin_arm_crc32d: +    CRCIntrinsicID = Intrinsic::arm_crc32w; break; +  case ARM::BI__builtin_arm_crc32cw: +  case ARM::BI__builtin_arm_crc32cd: +    CRCIntrinsicID = Intrinsic::arm_crc32cw; break; +  } + +  if (CRCIntrinsicID != Intrinsic::not_intrinsic) { +    Value *Arg0 = EmitScalarExpr(E->getArg(0)); +    Value *Arg1 = EmitScalarExpr(E->getArg(1)); + +    // crc32{c,}d intrinsics are implemnted as two calls to crc32{c,}w +    // intrinsics, hence we need different codegen for these cases. +    if (BuiltinID == ARM::BI__builtin_arm_crc32d || +        BuiltinID == ARM::BI__builtin_arm_crc32cd) { +      Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); +      Value *Arg1a = Builder.CreateTruncOrBitCast(Arg1, Int32Ty); +      Value *Arg1b = Builder.CreateLShr(Arg1, C1); +      Arg1b = Builder.CreateTruncOrBitCast(Arg1b, Int32Ty); + +      Function *F = CGM.getIntrinsic(CRCIntrinsicID); +      Value *Res = Builder.CreateCall2(F, Arg0, Arg1a); +      return Builder.CreateCall2(F, Res, Arg1b); +    } else { +      Arg1 = Builder.CreateZExtOrBitCast(Arg1, Int32Ty); + +      Function *F = CGM.getIntrinsic(CRCIntrinsicID); +      return Builder.CreateCall2(F, Arg0, Arg1); +    } +  } +    SmallVector<Value*, 4> Ops;    llvm::Value *Align = 0;    for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { @@ -1836,9 +4214,24 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,    case ARM::BI__builtin_neon_vabsq_v:      return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vabs, Ty),                          Ops, "vabs"); -  case ARM::BI__builtin_neon_vaddhn_v: -    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vaddhn, Ty), -                        Ops, "vaddhn"); +  case ARM::BI__builtin_neon_vaddhn_v: { +    llvm::VectorType *SrcTy = +        llvm::VectorType::getExtendedElementVectorType(VTy); + +    // %sum = add <4 x i32> %lhs, %rhs +    Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); +    Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); +    Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn"); + +    // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> +    Constant *ShiftAmt = ConstantInt::get(SrcTy->getElementType(), +                                       SrcTy->getScalarSizeInBits() / 2); +    ShiftAmt = ConstantVector::getSplat(VTy->getNumElements(), ShiftAmt); +    Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn"); + +    // %res = trunc <4 x i32> %high to <4 x i16> +    return Builder.CreateTrunc(Ops[0], VTy, "vaddhn"); +  }    case ARM::BI__builtin_neon_vcale_v:      std::swap(Ops[0], Ops[1]);    case ARM::BI__builtin_neon_vcage_v: { @@ -2142,6 +4535,11 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,      return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vmulp, Ty),                          Ops, "vmul");    case ARM::BI__builtin_neon_vmull_v: +    // FIXME: the integer vmull operations could be emitted in terms of pure +    // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of +    // hoisting the exts outside loops. Until global ISel comes along that can +    // see through such movement this leads to bad CodeGen. So we need an +    // intrinsic for now.      Int = usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls;      Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int;      return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); @@ -2195,12 +4593,28 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,    case ARM::BI__builtin_neon_vqaddq_v:      Int = usgn ? Intrinsic::arm_neon_vqaddu : Intrinsic::arm_neon_vqadds;      return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqadd"); -  case ARM::BI__builtin_neon_vqdmlal_v: -    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmlal, Ty), -                        Ops, "vqdmlal"); -  case ARM::BI__builtin_neon_vqdmlsl_v: -    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmlsl, Ty), -                        Ops, "vqdmlsl"); +  case ARM::BI__builtin_neon_vqdmlal_v: { +    SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end()); +    Value *Mul = EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, Ty), +                              MulOps, "vqdmlal"); + +    SmallVector<Value *, 2> AddOps; +    AddOps.push_back(Ops[0]); +    AddOps.push_back(Mul); +    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqadds, Ty), +                        AddOps, "vqdmlal"); +  } +  case ARM::BI__builtin_neon_vqdmlsl_v: { +    SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end()); +    Value *Mul = EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, Ty), +                              MulOps, "vqdmlsl"); + +    SmallVector<Value *, 2> SubOps; +    SubOps.push_back(Ops[0]); +    SubOps.push_back(Mul); +    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqsubs, Ty), +                        SubOps, "vqdmlsl"); +  }    case ARM::BI__builtin_neon_vqdmulh_v:    case ARM::BI__builtin_neon_vqdmulhq_v:      return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmulh, Ty), @@ -2320,12 +4734,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,                          Ops, "vshrn_n", 1, true);    case ARM::BI__builtin_neon_vshr_n_v:    case ARM::BI__builtin_neon_vshrq_n_v: -    Ops[0] = Builder.CreateBitCast(Ops[0], Ty); -    Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); -    if (usgn) -      return Builder.CreateLShr(Ops[0], Ops[1], "vshr_n"); -    else -      return Builder.CreateAShr(Ops[0], Ops[1], "vshr_n"); +    return EmitNeonRShiftImm(Ops[0], Ops[1], Ty, usgn, "vshr_n");    case ARM::BI__builtin_neon_vsri_n_v:    case ARM::BI__builtin_neon_vsriq_n_v:      rightShift = true; @@ -2337,12 +4746,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,    case ARM::BI__builtin_neon_vsra_n_v:    case ARM::BI__builtin_neon_vsraq_n_v:      Ops[0] = Builder.CreateBitCast(Ops[0], Ty); -    Ops[1] = Builder.CreateBitCast(Ops[1], Ty); -    Ops[2] = EmitNeonShiftVector(Ops[2], Ty, false); -    if (usgn) -      Ops[1] = Builder.CreateLShr(Ops[1], Ops[2], "vsra_n"); -    else -      Ops[1] = Builder.CreateAShr(Ops[1], Ops[2], "vsra_n"); +    Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n");      return Builder.CreateAdd(Ops[0], Ops[1]);    case ARM::BI__builtin_neon_vst1_v:    case ARM::BI__builtin_neon_vst1q_v: @@ -2400,9 +4804,24 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,      Ops.push_back(Align);      return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4lane, Ty),                          Ops, ""); -  case ARM::BI__builtin_neon_vsubhn_v: -    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vsubhn, Ty), -                        Ops, "vsubhn"); +  case ARM::BI__builtin_neon_vsubhn_v: { +    llvm::VectorType *SrcTy = +        llvm::VectorType::getExtendedElementVectorType(VTy); + +    // %sum = add <4 x i32> %lhs, %rhs +    Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); +    Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); +    Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn"); + +    // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> +    Constant *ShiftAmt = ConstantInt::get(SrcTy->getElementType(), +                                       SrcTy->getScalarSizeInBits() / 2); +    ShiftAmt = ConstantVector::getSplat(VTy->getNumElements(), ShiftAmt); +    Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn"); + +    // %res = trunc <4 x i32> %high to <4 x i16> +    return Builder.CreateTrunc(Ops[0], VTy, "vsubhn"); +  }    case ARM::BI__builtin_neon_vtbl1_v:      return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1),                          Ops, "vtbl1"); @@ -2560,19 +4979,15 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,      return Builder.CreateExtractElement(Ops[0],                                    llvm::ConstantInt::get(Ops[1]->getType(), 0));    case X86::BI__builtin_ia32_ldmxcsr: { -    llvm::Type *PtrTy = Int8PtrTy; -    Value *One = llvm::ConstantInt::get(Int32Ty, 1); -    Value *Tmp = Builder.CreateAlloca(Int32Ty, One); +    Value *Tmp = CreateMemTemp(E->getArg(0)->getType());      Builder.CreateStore(Ops[0], Tmp);      return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), -                              Builder.CreateBitCast(Tmp, PtrTy)); +                              Builder.CreateBitCast(Tmp, Int8PtrTy));    }    case X86::BI__builtin_ia32_stmxcsr: { -    llvm::Type *PtrTy = Int8PtrTy; -    Value *One = llvm::ConstantInt::get(Int32Ty, 1); -    Value *Tmp = Builder.CreateAlloca(Int32Ty, One); +    Value *Tmp = CreateMemTemp(E->getType());      Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), -                       Builder.CreateBitCast(Tmp, PtrTy)); +                       Builder.CreateBitCast(Tmp, Int8PtrTy));      return Builder.CreateLoad(Tmp, "stmxcsr");    }    case X86::BI__builtin_ia32_storehps: @@ -2697,7 +5112,8 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,    case X86::BI__builtin_ia32_movntpd256:    case X86::BI__builtin_ia32_movntdq:    case X86::BI__builtin_ia32_movntdq256: -  case X86::BI__builtin_ia32_movnti: { +  case X86::BI__builtin_ia32_movnti: +  case X86::BI__builtin_ia32_movnti64: {      llvm::MDNode *Node = llvm::MDNode::get(getLLVMContext(),                                             Builder.getInt32(1)); @@ -2707,7 +5123,16 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,                                        "cast");      StoreInst *SI = Builder.CreateStore(Ops[1], BC);      SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); -    SI->setAlignment(16); + +    // If the operand is an integer, we can't assume alignment. Otherwise, +    // assume natural alignment. +    QualType ArgTy = E->getArg(1)->getType(); +    unsigned Align; +    if (ArgTy->isIntegerType()) +      Align = 1; +    else +      Align = getContext().getTypeSizeInChars(ArgTy).getQuantity(); +    SI->setAlignment(Align);      return SI;    }    // 3DNow! @@ -2761,6 +5186,13 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,      Builder.CreateStore(Builder.CreateExtractValue(Call, 0), Ops[0]);      return Builder.CreateExtractValue(Call, 1);    } +  // AVX2 broadcast +  case X86::BI__builtin_ia32_vbroadcastsi256: { +    Value *VecTmp = CreateMemTemp(E->getArg(0)->getType()); +    Builder.CreateStore(Ops[0], VecTmp); +    Value *F = CGM.getIntrinsic(Intrinsic::x86_avx2_vbroadcasti128); +    return Builder.CreateCall(F, Builder.CreateBitCast(VecTmp, Int8PtrTy)); +  }    }  } diff --git a/lib/CodeGen/CGCUDARuntime.cpp b/lib/CodeGen/CGCUDARuntime.cpp index fc72008af8866..eaf31bb6f67f3 100644 --- a/lib/CodeGen/CGCUDARuntime.cpp +++ b/lib/CodeGen/CGCUDARuntime.cpp @@ -44,8 +44,8 @@ RValue CGCUDARuntime::EmitCUDAKernelCallExpr(CodeGenFunction &CGF,    }    llvm::Value *Callee = CGF.EmitScalarExpr(E->getCallee()); -  CGF.EmitCall(E->getCallee()->getType(), Callee, ReturnValue, -               E->arg_begin(), E->arg_end(), TargetDecl); +  CGF.EmitCall(E->getCallee()->getType(), Callee, E->getLocStart(), +               ReturnValue, E->arg_begin(), E->arg_end(), TargetDecl);    CGF.EmitBranch(ContBlock);    CGF.EmitBlock(ContBlock); diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 983cb9224ade7..cfb2d6291b8aa 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -34,6 +34,11 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {    if (!getCodeGenOpts().CXXCtorDtorAliases)      return true; +  // Producing an alias to a base class ctor/dtor can degrade debug quality +  // as the debugger cannot tell them appart. +  if (getCodeGenOpts().OptimizationLevel == 0) +    return true; +    // If the destructor doesn't have a trivial body, we have to emit it    // separately.    if (!D->hasTrivialBody()) @@ -82,60 +87,44 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {    if (!UniqueBase)      return true; -  /// If we don't have a definition for the destructor yet, don't -  /// emit.  We can't emit aliases to declarations; that's just not -  /// how aliases work. -  const CXXDestructorDecl *BaseD = UniqueBase->getDestructor(); -  if (!BaseD->isImplicit() && !BaseD->hasBody()) -    return true; -    // If the base is at a non-zero offset, give up.    const ASTRecordLayout &ClassLayout = Context.getASTRecordLayout(Class);    if (!ClassLayout.getBaseClassOffset(UniqueBase).isZero())      return true; +  const CXXDestructorDecl *BaseD = UniqueBase->getDestructor();    return TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Base), -                                  GlobalDecl(BaseD, Dtor_Base)); +                                  GlobalDecl(BaseD, Dtor_Base), +                                  false);  }  /// Try to emit a definition as a global alias for another definition. +/// If \p InEveryTU is true, we know that an equivalent alias can be produced +/// in every translation unit.  bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl, -                                             GlobalDecl TargetDecl) { +                                             GlobalDecl TargetDecl, +                                             bool InEveryTU) {    if (!getCodeGenOpts().CXXCtorDtorAliases)      return true;    // The alias will use the linkage of the referrent.  If we can't    // support aliases with that linkage, fail. -  llvm::GlobalValue::LinkageTypes Linkage -    = getFunctionLinkage(cast<FunctionDecl>(AliasDecl.getDecl())); - -  switch (Linkage) { -  // We can definitely emit aliases to definitions with external linkage. -  case llvm::GlobalValue::ExternalLinkage: -  case llvm::GlobalValue::ExternalWeakLinkage: -    break; - -  // Same with local linkage. -  case llvm::GlobalValue::InternalLinkage: -  case llvm::GlobalValue::PrivateLinkage: -  case llvm::GlobalValue::LinkerPrivateLinkage: -    break; - -  // We should try to support linkonce linkages. -  case llvm::GlobalValue::LinkOnceAnyLinkage: -  case llvm::GlobalValue::LinkOnceODRLinkage: -    return true; +  llvm::GlobalValue::LinkageTypes Linkage = getFunctionLinkage(AliasDecl); -  // Other linkages will probably never be supported. -  default: +  // We can't use an alias if the linkage is not valid for one. +  if (!llvm::GlobalAlias::isValidLinkage(Linkage))      return true; -  } -  llvm::GlobalValue::LinkageTypes TargetLinkage -    = getFunctionLinkage(cast<FunctionDecl>(TargetDecl.getDecl())); +  llvm::GlobalValue::LinkageTypes TargetLinkage = +      getFunctionLinkage(TargetDecl); -  if (llvm::GlobalValue::isWeakForLinker(TargetLinkage)) -    return true; +  // Check if we have it already. +  StringRef MangledName = getMangledName(AliasDecl); +  llvm::GlobalValue *Entry = GetGlobalValue(MangledName); +  if (Entry && !Entry->isDeclaration()) +    return false; +  if (Replacements.count(MangledName)) +    return false;    // Derive the type for the alias.    llvm::PointerType *AliasType @@ -149,15 +138,41 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,    if (Ref->getType() != AliasType)      Aliasee = llvm::ConstantExpr::getBitCast(Ref, AliasType); +  // Instead of creating as alias to a linkonce_odr, replace all of the uses +  // of the aliassee. +  if (llvm::GlobalValue::isDiscardableIfUnused(Linkage) && +     (TargetLinkage != llvm::GlobalValue::AvailableExternallyLinkage || +      !TargetDecl.getDecl()->hasAttr<AlwaysInlineAttr>())) { +    // FIXME: An extern template instanciation will create functions with +    // linkage "AvailableExternally". In libc++, some classes also define +    // members with attribute "AlwaysInline" and expect no reference to +    // be generated. It is desirable to reenable this optimisation after +    // corresponding LLVM changes. +    Replacements[MangledName] = Aliasee; +    return false; +  } + +  if (!InEveryTU) { +    /// If we don't have a definition for the destructor yet, don't +    /// emit.  We can't emit aliases to declarations; that's just not +    /// how aliases work. +    if (Ref->isDeclaration()) +      return true; +  } + +  // Don't create an alias to a linker weak symbol. This avoids producing +  // different COMDATs in different TUs. Another option would be to +  // output the alias both for weak_odr and linkonce_odr, but that +  // requires explicit comdat support in the IL. +  if (llvm::GlobalValue::isWeakForLinker(TargetLinkage)) +    return true; +    // Create the alias with no name.    llvm::GlobalAlias *Alias =       new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule());    // Switch any previous uses to the alias. -  StringRef MangledName = getMangledName(AliasDecl); -  llvm::GlobalValue *Entry = GetGlobalValue(MangledName);    if (Entry) { -    assert(Entry->isDeclaration() && "definition already exists for alias");      assert(Entry->getType() == AliasType &&             "declaration exists with different type");      Alias->takeName(Entry); @@ -173,37 +188,26 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,    return false;  } -void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) { -  // The constructor used for constructing this as a complete class; -  // constucts the virtual bases, then calls the base constructor. -  if (!D->getParent()->isAbstract()) { -    // We don't need to emit the complete ctor if the class is abstract. -    EmitGlobal(GlobalDecl(D, Ctor_Complete)); -  } - -  // The constructor used for constructing this as a base class; -  // ignores virtual bases. -  if (getTarget().getCXXABI().hasConstructorVariants()) -    EmitGlobal(GlobalDecl(D, Ctor_Base)); -} -  void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *ctor,                                         CXXCtorType ctorType) {    // The complete constructor is equivalent to the base constructor    // for classes with no virtual bases.  Try to emit it as an alias.    if (getTarget().getCXXABI().hasConstructorVariants() && -      ctorType == Ctor_Complete &&        !ctor->getParent()->getNumVBases() && -      !TryEmitDefinitionAsAlias(GlobalDecl(ctor, Ctor_Complete), -                                GlobalDecl(ctor, Ctor_Base))) -    return; +      (ctorType == Ctor_Complete || ctorType == Ctor_Base)) { +    bool ProducedAlias = +        !TryEmitDefinitionAsAlias(GlobalDecl(ctor, Ctor_Complete), +                                  GlobalDecl(ctor, Ctor_Base), true); +    if (ctorType == Ctor_Complete && ProducedAlias) +      return; +  }    const CGFunctionInfo &fnInfo =      getTypes().arrangeCXXConstructorDeclaration(ctor, ctorType);    llvm::Function *fn =      cast<llvm::Function>(GetAddrOfCXXConstructor(ctor, ctorType, &fnInfo)); -  setFunctionLinkage(ctor, fn); +  setFunctionLinkage(GlobalDecl(ctor, ctorType), fn);    CodeGenFunction(*this).GenerateCode(GlobalDecl(ctor, ctorType), fn, fnInfo); @@ -229,31 +233,22 @@ CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor,                                                        /*ForVTable=*/false));  } -void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) { -  // The destructor in a virtual table is always a 'deleting' -  // destructor, which calls the complete destructor and then uses the -  // appropriate operator delete. -  if (D->isVirtual()) -    EmitGlobal(GlobalDecl(D, Dtor_Deleting)); - -  // The destructor used for destructing this as a most-derived class; -  // call the base destructor and then destructs any virtual bases. -  EmitGlobal(GlobalDecl(D, Dtor_Complete)); - -  // The destructor used for destructing this as a base class; ignores -  // virtual bases. -  EmitGlobal(GlobalDecl(D, Dtor_Base)); -} -  void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *dtor,                                        CXXDtorType dtorType) {    // The complete destructor is equivalent to the base destructor for    // classes with no virtual bases, so try to emit it as an alias. -  if (dtorType == Dtor_Complete && -      !dtor->getParent()->getNumVBases() && -      !TryEmitDefinitionAsAlias(GlobalDecl(dtor, Dtor_Complete), -                                GlobalDecl(dtor, Dtor_Base))) -    return; +  if (!dtor->getParent()->getNumVBases() && +      (dtorType == Dtor_Complete || dtorType == Dtor_Base)) { +    bool ProducedAlias = +        !TryEmitDefinitionAsAlias(GlobalDecl(dtor, Dtor_Complete), +                                  GlobalDecl(dtor, Dtor_Base), true); +    if (ProducedAlias) { +      if (dtorType == Dtor_Complete) +        return; +      if (dtor->isVirtual()) +        getVTables().EmitThunks(GlobalDecl(dtor, Dtor_Complete)); +    } +  }    // The base destructor is equivalent to the base destructor of its    // base class if there is exactly one non-virtual base class with a @@ -267,7 +262,7 @@ void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *dtor,    llvm::Function *fn =      cast<llvm::Function>(GetAddrOfCXXDestructor(dtor, dtorType, &fnInfo)); -  setFunctionLinkage(dtor, fn); +  setFunctionLinkage(GlobalDecl(dtor, dtorType), fn);    CodeGenFunction(*this).GenerateCode(GlobalDecl(dtor, dtorType), fn, fnInfo); @@ -278,47 +273,51 @@ void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *dtor,  llvm::GlobalValue *  CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor,                                        CXXDtorType dtorType, -                                      const CGFunctionInfo *fnInfo) { +                                      const CGFunctionInfo *fnInfo, +                                      llvm::FunctionType *fnType) {    GlobalDecl GD(dtor, dtorType);    StringRef name = getMangledName(GD);    if (llvm::GlobalValue *existing = GetGlobalValue(name))      return existing; -  if (!fnInfo) fnInfo = &getTypes().arrangeCXXDestructor(dtor, dtorType); - -  llvm::FunctionType *fnType = getTypes().GetFunctionType(*fnInfo); +  if (!fnType) { +    if (!fnInfo) fnInfo = &getTypes().arrangeCXXDestructor(dtor, dtorType); +    fnType = getTypes().GetFunctionType(*fnInfo); +  }    return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD,                                                        /*ForVTable=*/false));  } -static llvm::Value *BuildVirtualCall(CodeGenFunction &CGF, uint64_t VTableIndex,  -                                     llvm::Value *This, llvm::Type *Ty) { +static llvm::Value *BuildAppleKextVirtualCall(CodeGenFunction &CGF, +                                              GlobalDecl GD, +                                              llvm::Type *Ty, +                                              const CXXRecordDecl *RD) { +  assert(!CGF.CGM.getTarget().getCXXABI().isMicrosoft() && +         "No kext in Microsoft ABI"); +  GD = GD.getCanonicalDecl(); +  CodeGenModule &CGM = CGF.CGM; +  llvm::Value *VTable = CGM.getCXXABI().getAddrOfVTable(RD, CharUnits());    Ty = Ty->getPointerTo()->getPointerTo(); -   -  llvm::Value *VTable = CGF.GetVTablePtr(This, Ty); -  llvm::Value *VFuncPtr =  -    CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn"); +  VTable = CGF.Builder.CreateBitCast(VTable, Ty); +  assert(VTable && "BuildVirtualCall = kext vtbl pointer is null"); +  uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD); +  uint64_t AddressPoint = +    CGM.getItaniumVTableContext().getVTableLayout(RD) +       .getAddressPoint(BaseSubobject(RD, CharUnits::Zero())); +  VTableIndex += AddressPoint; +  llvm::Value *VFuncPtr = +    CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt");    return CGF.Builder.CreateLoad(VFuncPtr);  } -llvm::Value * -CodeGenFunction::BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This, -                                  llvm::Type *Ty) { -  MD = MD->getCanonicalDecl(); -  uint64_t VTableIndex = CGM.getVTableContext().getMethodVTableIndex(MD); -   -  return ::BuildVirtualCall(*this, VTableIndex, This, Ty); -} - -/// BuildVirtualCall - This routine is to support gcc's kext ABI making +/// BuildAppleKextVirtualCall - This routine is to support gcc's kext ABI making  /// indirect call to virtual functions. It makes the call through indexing  /// into the vtable.  llvm::Value *  CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD,                                     NestedNameSpecifier *Qual,                                    llvm::Type *Ty) { -  llvm::Value *VTable = 0;    assert((Qual->getKind() == NestedNameSpecifier::TypeSpec) &&           "BuildAppleKextVirtualCall - bad Qual kind"); @@ -330,20 +329,8 @@ CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD,    if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD))      return BuildAppleKextVirtualDestructorCall(DD, Dtor_Complete, RD); -   -  VTable = CGM.getVTables().GetAddrOfVTable(RD); -  Ty = Ty->getPointerTo()->getPointerTo(); -  VTable = Builder.CreateBitCast(VTable, Ty); -  assert(VTable && "BuildVirtualCall = kext vtbl pointer is null"); -  MD = MD->getCanonicalDecl(); -  uint64_t VTableIndex = CGM.getVTableContext().getMethodVTableIndex(MD); -  uint64_t AddressPoint =  -    CGM.getVTableContext().getVTableLayout(RD) -       .getAddressPoint(BaseSubobject(RD, CharUnits::Zero())); -  VTableIndex += AddressPoint; -  llvm::Value *VFuncPtr =  -    Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt"); -  return Builder.CreateLoad(VFuncPtr); + +  return ::BuildAppleKextVirtualCall(*this, MD, Ty, RD);  }  /// BuildVirtualCall - This routine makes indirect vtable call for @@ -353,42 +340,16 @@ CodeGenFunction::BuildAppleKextVirtualDestructorCall(                                              const CXXDestructorDecl *DD,                                              CXXDtorType Type,                                              const CXXRecordDecl *RD) { -  llvm::Value * Callee = 0;    const CXXMethodDecl *MD = cast<CXXMethodDecl>(DD);    // FIXME. Dtor_Base dtor is always direct!!    // It need be somehow inline expanded into the caller.    // -O does that. But need to support -O0 as well.    if (MD->isVirtual() && Type != Dtor_Base) {      // Compute the function type we're calling. -    const CGFunctionInfo &FInfo =  -      CGM.getTypes().arrangeCXXDestructor(cast<CXXDestructorDecl>(MD), -                                          Dtor_Complete); +    const CGFunctionInfo &FInfo = +      CGM.getTypes().arrangeCXXDestructor(DD, Dtor_Complete);      llvm::Type *Ty = CGM.getTypes().GetFunctionType(FInfo); - -    llvm::Value *VTable = CGM.getVTables().GetAddrOfVTable(RD); -    Ty = Ty->getPointerTo()->getPointerTo(); -    VTable = Builder.CreateBitCast(VTable, Ty); -    DD = cast<CXXDestructorDecl>(DD->getCanonicalDecl()); -    uint64_t VTableIndex =  -      CGM.getVTableContext().getMethodVTableIndex(GlobalDecl(DD, Type)); -    uint64_t AddressPoint = -      CGM.getVTableContext().getVTableLayout(RD) -         .getAddressPoint(BaseSubobject(RD, CharUnits::Zero())); -    VTableIndex += AddressPoint; -    llvm::Value *VFuncPtr = -      Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt"); -    Callee = Builder.CreateLoad(VFuncPtr); +    return ::BuildAppleKextVirtualCall(*this, GlobalDecl(DD, Type), Ty, RD);    } -  return Callee; +  return 0;  } - -llvm::Value * -CodeGenFunction::BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type,  -                                  llvm::Value *This, llvm::Type *Ty) { -  DD = cast<CXXDestructorDecl>(DD->getCanonicalDecl()); -  uint64_t VTableIndex =  -    CGM.getVTableContext().getMethodVTableIndex(GlobalDecl(DD, Type)); - -  return ::BuildVirtualCall(*this, VTableIndex, This, Ty); -} - diff --git a/lib/CodeGen/CGCXXABI.cpp b/lib/CodeGen/CGCXXABI.cpp index 68fecb2d0cb82..412b27814ac87 100644 --- a/lib/CodeGen/CGCXXABI.cpp +++ b/lib/CodeGen/CGCXXABI.cpp @@ -1,4 +1,4 @@ -//===----- CGCXXABI.cpp - Interface to C++ ABIs -----------------*- C++ -*-===// +//===----- CGCXXABI.cpp - Interface to C++ ABIs ---------------------------===//  //  //                     The LLVM Compiler Infrastructure  // @@ -212,13 +212,6 @@ llvm::Value *CGCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,    return llvm::ConstantInt::get(CGF.SizeTy, 0);  } -void CGCXXABI::EmitGuardedInit(CodeGenFunction &CGF, -                               const VarDecl &D, -                               llvm::GlobalVariable *GV, -                               bool PerformInit) { -  ErrorUnsupportedABI(CGF, "static local variable initialization"); -} -  void CGCXXABI::registerGlobalDtor(CodeGenFunction &CGF,                                    const VarDecl &D,                                    llvm::Constant *dtor, @@ -227,7 +220,7 @@ void CGCXXABI::registerGlobalDtor(CodeGenFunction &CGF,      CGM.ErrorUnsupported(&D, "non-trivial TLS destruction");    // The default behavior is to use atexit. -  CGF.registerGlobalDtorWithAtExit(dtor, addr); +  CGF.registerGlobalDtorWithAtExit(D, dtor, addr);  }  /// Returns the adjustment, in bytes, required for the given @@ -251,8 +244,31 @@ llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) {                                            E->path_end());  } -llvm::BasicBlock *CGCXXABI::EmitCtorCompleteObjectHandler( -                                                         CodeGenFunction &CGF) { +CharUnits CGCXXABI::getMemberPointerPathAdjustment(const APValue &MP) { +  // TODO: Store base specifiers in APValue member pointer paths so we can +  // easily reuse CGM.GetNonVirtualBaseClassOffset(). +  const ValueDecl *MPD = MP.getMemberPointerDecl(); +  CharUnits ThisAdjustment = CharUnits::Zero(); +  ArrayRef<const CXXRecordDecl*> Path = MP.getMemberPointerPath(); +  bool DerivedMember = MP.isMemberPointerToDerivedMember(); +  const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPD->getDeclContext()); +  for (unsigned I = 0, N = Path.size(); I != N; ++I) { +    const CXXRecordDecl *Base = RD; +    const CXXRecordDecl *Derived = Path[I]; +    if (DerivedMember) +      std::swap(Base, Derived); +    ThisAdjustment += +      getContext().getASTRecordLayout(Derived).getBaseClassOffset(Base); +    RD = Path[I]; +  } +  if (DerivedMember) +    ThisAdjustment = -ThisAdjustment; +  return ThisAdjustment; +} + +llvm::BasicBlock * +CGCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, +                                        const CXXRecordDecl *RD) {    if (CGM.getTarget().getCXXABI().hasConstructorVariants())      llvm_unreachable("shouldn't be called in this ABI"); @@ -270,3 +286,7 @@ LValue CGCXXABI::EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,    ErrorUnsupportedABI(CGF, "odr-use of thread_local global");    return LValue();  } + +bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) { +  return false; +} diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h index 1e4da631d6f66..9e9a2a7aaf9b3 100644 --- a/lib/CodeGen/CGCXXABI.h +++ b/lib/CodeGen/CGCXXABI.h @@ -97,8 +97,12 @@ public:      return *MangleCtx;    } -  /// Returns true if the given instance method is one of the -  /// kinds that the ABI says returns 'this'. +  /// Returns true if the given constructor or destructor is one of the +  /// kinds that the ABI says returns 'this' (only applies when called +  /// non-virtually for destructors). +  /// +  /// There currently is no way to indicate if a destructor returns 'this' +  /// when called virtually, and code generation does not support the case.    virtual bool HasThisReturn(GlobalDecl GD) const { return false; }    /// Returns true if the given record type should be returned indirectly. @@ -192,6 +196,12 @@ protected:    /// is required.    llvm::Constant *getMemberPointerAdjustment(const CastExpr *E); +  /// \brief Computes the non-virtual adjustment needed for a member pointer +  /// conversion along an inheritance path stored in an APValue.  Unlike +  /// getMemberPointerAdjustment(), the adjustment can be negative if the path +  /// is from a derived type to a base type. +  CharUnits getMemberPointerPathAdjustment(const APValue &MP); +  public:    /// Adjust the given non-null pointer to an object of polymorphic    /// type to point to the complete object. @@ -202,11 +212,16 @@ public:                                                llvm::Value *ptr,                                                QualType type) = 0; +  virtual llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF, +                                                 llvm::Value *This, +                                                 const CXXRecordDecl *ClassDecl, +                                        const CXXRecordDecl *BaseClassDecl) = 0; +    /// Build the signature of the given constructor variant by adding -  /// any required parameters.  For convenience, ResTy has been -  /// initialized to 'void', and ArgTys has been initialized with the -  /// type of 'this' (although this may be changed by the ABI) and -  /// will have the formal parameters added to it afterwards. +  /// any required parameters.  For convenience, ArgTys has been initialized +  /// with the type of 'this' and ResTy has been initialized with the type of +  /// 'this' if HasThisReturn(GlobalDecl(Ctor, T)) is true or 'void' otherwise +  /// (although both may be changed by the ABI).    ///    /// If there are ever any ABIs where the implicit parameters are    /// intermixed with the formal parameters, we can address those @@ -216,46 +231,138 @@ public:                                           CanQualType &ResTy,                                 SmallVectorImpl<CanQualType> &ArgTys) = 0; -  virtual llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF); +  virtual llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, +                                                          const CXXRecordDecl *RD); + +  /// Emit the code to initialize hidden members required +  /// to handle virtual inheritance, if needed by the ABI. +  virtual void +  initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF, +                                            const CXXRecordDecl *RD) {} + +  /// Emit constructor variants required by this ABI. +  virtual void EmitCXXConstructors(const CXXConstructorDecl *D) = 0;    /// Build the signature of the given destructor variant by adding -  /// any required parameters.  For convenience, ResTy has been -  /// initialized to 'void' and ArgTys has been initialized with the -  /// type of 'this' (although this may be changed by the ABI). +  /// any required parameters.  For convenience, ArgTys has been initialized +  /// with the type of 'this' and ResTy has been initialized with the type of +  /// 'this' if HasThisReturn(GlobalDecl(Dtor, T)) is true or 'void' otherwise +  /// (although both may be changed by the ABI).    virtual void BuildDestructorSignature(const CXXDestructorDecl *Dtor,                                          CXXDtorType T,                                          CanQualType &ResTy,                                 SmallVectorImpl<CanQualType> &ArgTys) = 0; +  /// Returns true if the given destructor type should be emitted as a linkonce +  /// delegating thunk, regardless of whether the dtor is defined in this TU or +  /// not. +  virtual bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, +                                      CXXDtorType DT) const = 0; + +  /// Emit destructor variants required by this ABI. +  virtual void EmitCXXDestructors(const CXXDestructorDecl *D) = 0; + +  /// Get the type of the implicit "this" parameter used by a method. May return +  /// zero if no specific type is applicable, e.g. if the ABI expects the "this" +  /// parameter to point to some artificial offset in a complete object due to +  /// vbases being reordered. +  virtual const CXXRecordDecl * +  getThisArgumentTypeForMethod(const CXXMethodDecl *MD) { +    return MD->getParent(); +  } + +  /// Perform ABI-specific "this" argument adjustment required prior to +  /// a virtual function call. +  virtual llvm::Value *adjustThisArgumentForVirtualCall(CodeGenFunction &CGF, +                                                        GlobalDecl GD, +                                                        llvm::Value *This) { +    return This; +  } +    /// Build the ABI-specific portion of the parameter list for a    /// function.  This generally involves a 'this' parameter and    /// possibly some extra data for constructors and destructors.    ///    /// ABIs may also choose to override the return type, which has been -  /// initialized with the formal return type of the function. +  /// initialized with the type of 'this' if HasThisReturn(CGF.CurGD) is true or +  /// the formal return type of the function otherwise.    virtual void BuildInstanceFunctionParams(CodeGenFunction &CGF,                                             QualType &ResTy,                                             FunctionArgList &Params) = 0; +  /// Perform ABI-specific "this" parameter adjustment in a virtual function +  /// prologue. +  virtual llvm::Value *adjustThisParameterInVirtualFunctionPrologue( +      CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This) { +    return This; +  } +    /// Emit the ABI-specific prolog for the function.    virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF) = 0;    /// Emit the constructor call. Return the function that is called. -  virtual llvm::Value *EmitConstructorCall(CodeGenFunction &CGF, +  virtual void EmitConstructorCall(CodeGenFunction &CGF,                                     const CXXConstructorDecl *D, -                                   CXXCtorType Type, bool ForVirtualBase, -                                   bool Delegating, +                                   CXXCtorType Type, +                                   bool ForVirtualBase, bool Delegating,                                     llvm::Value *This,                                     CallExpr::const_arg_iterator ArgBeg,                                     CallExpr::const_arg_iterator ArgEnd) = 0; +  /// Emits the VTable definitions required for the given record type. +  virtual void emitVTableDefinitions(CodeGenVTables &CGVT, +                                     const CXXRecordDecl *RD) = 0; + +  /// Get the address point of the vtable for the given base subobject while +  /// building a constructor or a destructor. On return, NeedsVirtualOffset +  /// tells if a virtual base adjustment is needed in order to get the offset +  /// of the base subobject. +  virtual llvm::Value *getVTableAddressPointInStructor( +      CodeGenFunction &CGF, const CXXRecordDecl *RD, BaseSubobject Base, +      const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) = 0; + +  /// Get the address point of the vtable for the given base subobject while +  /// building a constexpr. +  virtual llvm::Constant * +  getVTableAddressPointForConstExpr(BaseSubobject Base, +                                    const CXXRecordDecl *VTableClass) = 0; + +  /// Get the address of the vtable for the given record decl which should be +  /// used for the vptr at the given offset in RD. +  virtual llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, +                                                CharUnits VPtrOffset) = 0; + +  /// Build a virtual function pointer in the ABI-specific way. +  virtual llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, +                                                 GlobalDecl GD, +                                                 llvm::Value *This, +                                                 llvm::Type *Ty) = 0; +    /// Emit the ABI-specific virtual destructor call. -  virtual RValue EmitVirtualDestructorCall(CodeGenFunction &CGF, -                                           const CXXDestructorDecl *Dtor, -                                           CXXDtorType DtorType, -                                           SourceLocation CallLoc, -                                           ReturnValueSlot ReturnValue, -                                           llvm::Value *This) = 0; +  virtual void EmitVirtualDestructorCall(CodeGenFunction &CGF, +                                         const CXXDestructorDecl *Dtor, +                                         CXXDtorType DtorType, +                                         SourceLocation CallLoc, +                                         llvm::Value *This) = 0; + +  virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, +                                                GlobalDecl GD, +                                                CallArgList &CallArgs) {} + +  /// Emit any tables needed to implement virtual inheritance.  For Itanium, +  /// this emits virtual table tables.  For the MSVC++ ABI, this emits virtual +  /// base tables. +  virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD) = 0; + +  virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) = 0; + +  virtual llvm::Value *performThisAdjustment(CodeGenFunction &CGF, +                                             llvm::Value *This, +                                             const ThisAdjustment &TA) = 0; + +  virtual llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, +                                               llvm::Value *Ret, +                                               const ReturnAdjustment &RA) = 0;    virtual void EmitReturnFromThunk(CodeGenFunction &CGF,                                     RValue RV, QualType ResultType); @@ -266,6 +373,10 @@ public:    /// Gets the deleted virtual member call name.    virtual StringRef GetDeletedVirtualCallName() = 0; +  /// \brief Returns true iff static data members that are initialized in the +  /// class definition should have linkonce linkage. +  virtual bool isInlineInitializedStaticDataMemberLinkOnce() { return false; } +    /**************************** Array cookies ******************************/    /// Returns the extra size required in order to store the array @@ -312,6 +423,9 @@ public:                                 QualType ElementType, llvm::Value *&NumElements,                                 llvm::Value *&AllocPtr, CharUnits &CookieSize); +  /// Return whether the given global decl needs a VTT parameter. +  virtual bool NeedsVTTParameter(GlobalDecl GD); +  protected:    /// Returns the extra size required in order to store the array    /// cookie for the given type.  Assumes that an array cookie is @@ -344,7 +458,8 @@ public:    ///   - a static local variable    ///   - a static data member of a class template instantiation    virtual void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, -                               llvm::GlobalVariable *DeclPtr, bool PerformInit); +                               llvm::GlobalVariable *DeclPtr, +                               bool PerformInit) = 0;    /// Emit code to force the execution of a destructor during global    /// teardown.  The default implementation of this uses atexit. diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index b0f460ec0e7b7..22f2467021e1c 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1,4 +1,4 @@ -//===--- CGCall.cpp - Encapsulate calling convention details ----*- C++ -*-===// +//===--- CGCall.cpp - Encapsulate calling convention details --------------===//  //  //                     The LLVM Compiler Infrastructure  // @@ -22,6 +22,7 @@  #include "clang/AST/DeclCXX.h"  #include "clang/AST/DeclObjC.h"  #include "clang/Basic/TargetInfo.h" +#include "clang/CodeGen/CGFunctionInfo.h"  #include "clang/Frontend/CodeGenOptions.h"  #include "llvm/ADT/StringExtras.h"  #include "llvm/IR/Attributes.h" @@ -41,6 +42,8 @@ static unsigned ClangCallConvToLLVMCallConv(CallingConv CC) {    case CC_X86StdCall: return llvm::CallingConv::X86_StdCall;    case CC_X86FastCall: return llvm::CallingConv::X86_FastCall;    case CC_X86ThisCall: return llvm::CallingConv::X86_ThisCall; +  case CC_X86_64Win64: return llvm::CallingConv::X86_64_Win64; +  case CC_X86_64SysV: return llvm::CallingConv::X86_64_SysV;    case CC_AAPCS: return llvm::CallingConv::ARM_AAPCS;    case CC_AAPCS_VFP: return llvm::CallingConv::ARM_AAPCS_VFP;    case CC_IntelOclBicc: return llvm::CallingConv::Intel_OCL_BI; @@ -103,24 +106,12 @@ static const CGFunctionInfo &arrangeFreeFunctionType(CodeGenTypes &CGT,    return arrangeLLVMFunctionInfo(CGT, prefix, FTP, FTP->getExtInfo());  } -/// Given the formal ext-info of a C++ instance method, adjust it -/// according to the C++ ABI in effect. -static void adjustCXXMethodInfo(CodeGenTypes &CGT, -                                FunctionType::ExtInfo &extInfo, -                                bool isVariadic) { -  if (extInfo.getCC() == CC_Default) { -    CallingConv CC = CGT.getContext().getDefaultCXXMethodCallConv(isVariadic); -    extInfo = extInfo.withCallingConv(CC); -  } -} -  /// Arrange the argument and result information for a free function (i.e.  /// not a C++ or ObjC instance method) of the given type.  static const CGFunctionInfo &arrangeCXXMethodType(CodeGenTypes &CGT,                                        SmallVectorImpl<CanQualType> &prefix,                                              CanQual<FunctionProtoType> FTP) {    FunctionType::ExtInfo extInfo = FTP->getExtInfo(); -  adjustCXXMethodInfo(CGT, extInfo, FTP->isVariadic());    return arrangeLLVMFunctionInfo(CGT, prefix, FTP, extInfo);  } @@ -160,6 +151,8 @@ static CallingConv getCallingConventionForDecl(const Decl *D) {  /// Arrange the argument and result information for a call to an  /// unknown C++ non-static member function of the given abstract type. +/// (Zero value of RD means we don't have any meaningful "this" argument type, +///  so fall back to a generic pointer type).  /// The member function must be an ordinary function, i.e. not a  /// constructor or destructor.  const CGFunctionInfo & @@ -168,7 +161,10 @@ CodeGenTypes::arrangeCXXMethodType(const CXXRecordDecl *RD,    SmallVector<CanQualType, 16> argTypes;    // Add the 'this' pointer. -  argTypes.push_back(GetThisType(Context, RD)); +  if (RD) +    argTypes.push_back(GetThisType(Context, RD)); +  else +    argTypes.push_back(Context.VoidPtrTy);    return ::arrangeCXXMethodType(*this, argTypes,                FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>()); @@ -180,14 +176,15 @@ CodeGenTypes::arrangeCXXMethodType(const CXXRecordDecl *RD,  /// constructor or destructor.  const CGFunctionInfo &  CodeGenTypes::arrangeCXXMethodDeclaration(const CXXMethodDecl *MD) { -  assert(!isa<CXXConstructorDecl>(MD) && "wrong method for contructors!"); +  assert(!isa<CXXConstructorDecl>(MD) && "wrong method for constructors!");    assert(!isa<CXXDestructorDecl>(MD) && "wrong method for destructors!");    CanQual<FunctionProtoType> prototype = GetFormalType(MD);    if (MD->isInstance()) {      // The abstract case is perfectly fine. -    return arrangeCXXMethodType(MD->getParent(), prototype.getTypePtr()); +    const CXXRecordDecl *ThisType = TheCXXABI.getThisArgumentTypeForMethod(MD); +    return arrangeCXXMethodType(ThisType, prototype.getTypePtr());    }    return arrangeFreeFunctionType(prototype); @@ -200,7 +197,10 @@ CodeGenTypes::arrangeCXXConstructorDeclaration(const CXXConstructorDecl *D,                                                 CXXCtorType ctorKind) {    SmallVector<CanQualType, 16> argTypes;    argTypes.push_back(GetThisType(Context, D->getParent())); -  CanQualType resultType = Context.VoidTy; + +  GlobalDecl GD(D, ctorKind); +  CanQualType resultType = +    TheCXXABI.HasThisReturn(GD) ? argTypes.front() : Context.VoidTy;    TheCXXABI.BuildConstructorSignature(D, ctorKind, resultType, argTypes); @@ -213,7 +213,6 @@ CodeGenTypes::arrangeCXXConstructorDeclaration(const CXXConstructorDecl *D,      argTypes.push_back(FTP->getArgType(i));    FunctionType::ExtInfo extInfo = FTP->getExtInfo(); -  adjustCXXMethodInfo(*this, extInfo, FTP->isVariadic());    return arrangeLLVMFunctionInfo(resultType, argTypes, extInfo, required);  } @@ -225,7 +224,10 @@ CodeGenTypes::arrangeCXXDestructor(const CXXDestructorDecl *D,                                     CXXDtorType dtorKind) {    SmallVector<CanQualType, 2> argTypes;    argTypes.push_back(GetThisType(Context, D->getParent())); -  CanQualType resultType = Context.VoidTy; + +  GlobalDecl GD(D, dtorKind); +  CanQualType resultType = +    TheCXXABI.HasThisReturn(GD) ? argTypes.front() : Context.VoidTy;    TheCXXABI.BuildDestructorSignature(D, dtorKind, resultType, argTypes); @@ -234,7 +236,6 @@ CodeGenTypes::arrangeCXXDestructor(const CXXDestructorDecl *D,    assert(FTP->isVariadic() == 0 && "dtor with formal parameters");    FunctionType::ExtInfo extInfo = FTP->getExtInfo(); -  adjustCXXMethodInfo(*this, extInfo, false);    return arrangeLLVMFunctionInfo(resultType, argTypes, extInfo,                                   RequiredArgs::All);  } @@ -322,6 +323,7 @@ CodeGenTypes::arrangeGlobalDeclaration(GlobalDecl GD) {  /// additional number of formal parameters considered required.  static const CGFunctionInfo &  arrangeFreeFunctionLikeCall(CodeGenTypes &CGT, +                            CodeGenModule &CGM,                              const CallArgList &args,                              const FunctionType *fnType,                              unsigned numExtraRequiredArgs) { @@ -340,8 +342,9 @@ arrangeFreeFunctionLikeCall(CodeGenTypes &CGT,    // explicitly use the variadic convention for unprototyped calls,    // treat all of the arguments as required but preserve the nominal    // possibility of variadics. -  } else if (CGT.CGM.getTargetCodeGenInfo() -               .isNoProtoCallVariadic(args, cast<FunctionNoProtoType>(fnType))) { +  } else if (CGM.getTargetCodeGenInfo() +                .isNoProtoCallVariadic(args, +                                       cast<FunctionNoProtoType>(fnType))) {      required = RequiredArgs(args.size());    } @@ -356,7 +359,7 @@ arrangeFreeFunctionLikeCall(CodeGenTypes &CGT,  const CGFunctionInfo &  CodeGenTypes::arrangeFreeFunctionCall(const CallArgList &args,                                        const FunctionType *fnType) { -  return arrangeFreeFunctionLikeCall(*this, args, fnType, 0); +  return arrangeFreeFunctionLikeCall(*this, CGM, args, fnType, 0);  }  /// A block function call is essentially a free-function call with an @@ -364,7 +367,7 @@ CodeGenTypes::arrangeFreeFunctionCall(const CallArgList &args,  const CGFunctionInfo &  CodeGenTypes::arrangeBlockFunctionCall(const CallArgList &args,                                         const FunctionType *fnType) { -  return arrangeFreeFunctionLikeCall(*this, args, fnType, 1); +  return arrangeFreeFunctionLikeCall(*this, CGM, args, fnType, 1);  }  const CGFunctionInfo & @@ -393,7 +396,6 @@ CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args,      argTypes.push_back(Context.getCanonicalParamType(i->Ty));    FunctionType::ExtInfo info = FPT->getExtInfo(); -  adjustCXXMethodInfo(*this, info, FPT->isVariadic());    return arrangeLLVMFunctionInfo(GetReturnType(FPT->getResultType()),                                   argTypes, info, required);  } @@ -642,6 +644,10 @@ EnterStructPointerForCoercedAccess(llvm::Value *SrcPtr,  /// CoerceIntOrPtrToIntOrPtr - Convert a value Val to the specific Ty where both  /// are either integers or pointers.  This does a truncation of the value if it  /// is too large or a zero extension if it is too small. +/// +/// This behaves as if the value were coerced through memory, so on big-endian +/// targets the high bits are preserved in a truncation, while little-endian +/// targets preserve the low bits.  static llvm::Value *CoerceIntOrPtrToIntOrPtr(llvm::Value *Val,                                               llvm::Type *Ty,                                               CodeGenFunction &CGF) { @@ -661,8 +667,25 @@ static llvm::Value *CoerceIntOrPtrToIntOrPtr(llvm::Value *Val,    if (isa<llvm::PointerType>(DestIntTy))      DestIntTy = CGF.IntPtrTy; -  if (Val->getType() != DestIntTy) -    Val = CGF.Builder.CreateIntCast(Val, DestIntTy, false, "coerce.val.ii"); +  if (Val->getType() != DestIntTy) { +    const llvm::DataLayout &DL = CGF.CGM.getDataLayout(); +    if (DL.isBigEndian()) { +      // Preserve the high bits on big-endian targets. +      // That is what memory coercion does. +      uint64_t SrcSize = DL.getTypeAllocSizeInBits(Val->getType()); +      uint64_t DstSize = DL.getTypeAllocSizeInBits(DestIntTy); +      if (SrcSize > DstSize) { +        Val = CGF.Builder.CreateLShr(Val, SrcSize - DstSize, "coerce.highbits"); +        Val = CGF.Builder.CreateTrunc(Val, DestIntTy, "coerce.val.ii"); +      } else { +        Val = CGF.Builder.CreateZExt(Val, DestIntTy, "coerce.val.ii"); +        Val = CGF.Builder.CreateShl(Val, DstSize - SrcSize, "coerce.highbits"); +      } +    } else { +      // Little-endian targets preserve the low bits. No shifts required. +      Val = CGF.Builder.CreateIntCast(Val, DestIntTy, false, "coerce.val.ii"); +    } +  }    if (isa<llvm::PointerType>(Ty))      Val = CGF.Builder.CreateIntToPtr(Val, Ty, "coerce.val.ip"); @@ -1024,25 +1047,29 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,      // Attributes that should go on the function, but not the call site.      if (!CodeGenOpts.DisableFPElim) {        FuncAttrs.addAttribute("no-frame-pointer-elim", "false"); -      FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf", "false");      } else if (CodeGenOpts.OmitLeafFramePointer) {        FuncAttrs.addAttribute("no-frame-pointer-elim", "false"); -      FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf", "true"); +      FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf");      } else {        FuncAttrs.addAttribute("no-frame-pointer-elim", "true"); -      FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf", "true"); +      FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf");      }      FuncAttrs.addAttribute("less-precise-fpmad", -                           CodeGenOpts.LessPreciseFPMAD ? "true" : "false"); +                           llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD));      FuncAttrs.addAttribute("no-infs-fp-math", -                           CodeGenOpts.NoInfsFPMath ? "true" : "false"); +                           llvm::toStringRef(CodeGenOpts.NoInfsFPMath));      FuncAttrs.addAttribute("no-nans-fp-math", -                           CodeGenOpts.NoNaNsFPMath ? "true" : "false"); +                           llvm::toStringRef(CodeGenOpts.NoNaNsFPMath));      FuncAttrs.addAttribute("unsafe-fp-math", -                           CodeGenOpts.UnsafeFPMath ? "true" : "false"); +                           llvm::toStringRef(CodeGenOpts.UnsafeFPMath));      FuncAttrs.addAttribute("use-soft-float", -                           CodeGenOpts.SoftFloat ? "true" : "false"); +                           llvm::toStringRef(CodeGenOpts.SoftFloat)); +    FuncAttrs.addAttribute("stack-protector-buffer-size", +                           llvm::utostr(CodeGenOpts.SSPBufferSize)); + +    if (!CodeGenOpts.StackRealignment) +      FuncAttrs.addAttribute("no-realign-stack");    }    QualType RetTy = FI.getReturnType(); @@ -1050,12 +1077,15 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,    const ABIArgInfo &RetAI = FI.getReturnInfo();    switch (RetAI.getKind()) {    case ABIArgInfo::Extend: -   if (RetTy->hasSignedIntegerRepresentation()) -     RetAttrs.addAttribute(llvm::Attribute::SExt); -   else if (RetTy->hasUnsignedIntegerRepresentation()) -     RetAttrs.addAttribute(llvm::Attribute::ZExt); -    break; +    if (RetTy->hasSignedIntegerRepresentation()) +      RetAttrs.addAttribute(llvm::Attribute::SExt); +    else if (RetTy->hasUnsignedIntegerRepresentation()) +      RetAttrs.addAttribute(llvm::Attribute::ZExt); +    // FALL THROUGH    case ABIArgInfo::Direct: +    if (RetAI.getInReg()) +      RetAttrs.addAttribute(llvm::Attribute::InReg); +    break;    case ABIArgInfo::Ignore:      break; @@ -1263,7 +1293,8 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,        } else {          // Load scalar value from indirect argument.          CharUnits Alignment = getContext().getTypeAlignInChars(Ty); -        V = EmitLoadOfScalar(V, false, Alignment.getQuantity(), Ty); +        V = EmitLoadOfScalar(V, false, Alignment.getQuantity(), Ty, +                             Arg->getLocStart());          if (isPromoted)            V = emitArgumentDemotion(*this, Arg, V); @@ -1294,6 +1325,13 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,          if (isPromoted)            V = emitArgumentDemotion(*this, Arg, V); +        if (const CXXMethodDecl *MD = +            dyn_cast_or_null<CXXMethodDecl>(CurCodeDecl)) { +          if (MD->isVirtual() && Arg == CXXABIThisDecl) +            V = CGM.getCXXABI(). +                adjustThisParameterInVirtualFunctionPrologue(*this, CurGD, V); +        } +          // Because of merging of function types from multiple decls it is          // possible for the type of an argument to not match the corresponding          // type in the function type. Since we are codegening the callee @@ -1371,7 +1409,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,        // Match to what EmitParmDecl is expecting for this type.        if (CodeGenFunction::hasScalarEvaluationKind(Ty)) { -        V = EmitLoadOfScalar(V, false, AlignmentToUse, Ty); +        V = EmitLoadOfScalar(V, false, AlignmentToUse, Ty, Arg->getLocStart());          if (isPromoted)            V = emitArgumentDemotion(*this, Arg, V);        } @@ -1609,20 +1647,9 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {    return store;  } -/// Check whether 'this' argument of a callsite matches 'this' of the caller. -static bool checkThisPointer(llvm::Value *ThisArg, llvm::Value *This) { -  if (ThisArg == This) -    return true; -  // Check whether ThisArg is a bitcast of This. -  llvm::BitCastInst *Bitcast; -  if ((Bitcast = dyn_cast<llvm::BitCastInst>(ThisArg)) && -      Bitcast->getOperand(0) == This) -    return true; -  return false; -} -  void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI, -                                         bool EmitRetDbgLoc) { +                                         bool EmitRetDbgLoc, +                                         SourceLocation EndLoc) {    // Functions with no result always return void.    if (ReturnValue == 0) {      Builder.CreateRetVoid(); @@ -1639,7 +1666,8 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,      switch (getEvaluationKind(RetTy)) {      case TEK_Complex: {        ComplexPairTy RT = -        EmitLoadOfComplex(MakeNaturalAlignAddrLValue(ReturnValue, RetTy)); +        EmitLoadOfComplex(MakeNaturalAlignAddrLValue(ReturnValue, RetTy), +                          EndLoc);        EmitStoreOfComplex(RT,                         MakeNaturalAlignAddrLValue(CurFn->arg_begin(), RetTy),                           /*isInit*/ true); @@ -1667,8 +1695,10 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,        // If there is a dominating store to ReturnValue, we can elide        // the load, zap the store, and usually zap the alloca.        if (llvm::StoreInst *SI = findDominatingStoreToReturnValue(*this)) { -        // Reuse the debug location from the store unless we're told not to. -        if (EmitRetDbgLoc) +        // Reuse the debug location from the store unless there is +        // cleanup code to be emitted between the store and return +        // instruction. +        if (EmitRetDbgLoc && !AutoreleaseResult)            RetDbgLoc = SI->getDebugLoc();          // Get the stored value and nuke the now-dead store.          RV = SI->getValueOperand(); @@ -1715,26 +1745,14 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,      llvm_unreachable("Invalid ABI kind for return argument");    } -  // If this function returns 'this', the last instruction is a CallInst -  // that returns 'this', and 'this' argument of the CallInst points to -  // the same object as CXXThisValue, use the return value from the CallInst. -  // We will not need to keep 'this' alive through the callsite. It also enables -  // optimizations in the backend, such as tail call optimization. -  if (CalleeWithThisReturn && CGM.getCXXABI().HasThisReturn(CurGD)) { -    llvm::BasicBlock *IP = Builder.GetInsertBlock(); -    llvm::CallInst *Callsite; -    if (!IP->empty() && (Callsite = dyn_cast<llvm::CallInst>(&IP->back())) && -        Callsite->getCalledFunction() == CalleeWithThisReturn && -        checkThisPointer(Callsite->getOperand(0), CXXThisValue)) -      RV = Builder.CreateBitCast(Callsite, RetAI.getCoerceToType()); -  }    llvm::Instruction *Ret = RV ? Builder.CreateRet(RV) : Builder.CreateRetVoid();    if (!RetDbgLoc.isUnknown())      Ret->setDebugLoc(RetDbgLoc);  }  void CodeGenFunction::EmitDelegateCallArg(CallArgList &args, -                                          const VarDecl *param) { +                                          const VarDecl *param, +                                          SourceLocation loc) {    // StartFunction converted the ABI-lowered parameter(s) into a    // local alloca.  We need to turn that into an r-value suitable    // for EmitCall. @@ -1755,7 +1773,7 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args,      return args.add(RValue::get(Builder.CreateLoad(local)), type);    } -  args.add(convertTempToRValue(local, type), type); +  args.add(convertTempToRValue(local, type, loc), type);  }  static bool isProvablyNull(llvm::Value *addr) { @@ -1814,7 +1832,7 @@ static void emitWriteback(CodeGenFunction &CGF,      CGF.EmitARCIntrinsicUse(writeback.ToUse);      // Load the old value (primitively). -    llvm::Value *oldValue = CGF.EmitLoadOfScalar(srcLV); +    llvm::Value *oldValue = CGF.EmitLoadOfScalar(srcLV, SourceLocation());      // Put the new value in place (primitively).      CGF.EmitStoreOfScalar(value, srcLV, /*init*/ false); @@ -1839,6 +1857,19 @@ static void emitWritebacks(CodeGenFunction &CGF,      emitWriteback(CGF, *i);  } +static void deactivateArgCleanupsBeforeCall(CodeGenFunction &CGF, +                                            const CallArgList &CallArgs) { +  assert(CGF.getTarget().getCXXABI().isArgumentDestroyedByCallee()); +  ArrayRef<CallArgList::CallArgCleanup> Cleanups = +    CallArgs.getCleanupsToDeactivate(); +  // Iterate in reverse to increase the likelihood of popping the cleanup. +  for (ArrayRef<CallArgList::CallArgCleanup>::reverse_iterator +         I = Cleanups.rbegin(), E = Cleanups.rend(); I != E; ++I) { +    CGF.DeactivateCleanupBlock(I->Cleanup, I->IsActiveIP); +    I->IsActiveIP->eraseFromParent(); +  } +} +  static const Expr *maybeGetUnaryAddrOfOperand(const Expr *E) {    if (const UnaryOperator *uop = dyn_cast<UnaryOperator>(E->IgnoreParens()))      if (uop->getOpcode() == UO_AddrOf) @@ -1930,7 +1961,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args,    // Perform a copy if necessary.    if (shouldCopy) { -    RValue srcRV = CGF.EmitLoadOfLValue(srcLV); +    RValue srcRV = CGF.EmitLoadOfLValue(srcLV, SourceLocation());      assert(srcRV.isScalar());      llvm::Value *src = srcRV.getScalarVal(); @@ -1987,16 +2018,47 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,    if (E->isGLValue()) {      assert(E->getObjectKind() == OK_Ordinary); -    return args.add(EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0), -                    type); +    return args.add(EmitReferenceBindingToExpr(E), type); +  } + +  bool HasAggregateEvalKind = hasAggregateEvaluationKind(type); + +  // In the Microsoft C++ ABI, aggregate arguments are destructed by the callee. +  // However, we still have to push an EH-only cleanup in case we unwind before +  // we make it to the call. +  if (HasAggregateEvalKind && +      CGM.getTarget().getCXXABI().isArgumentDestroyedByCallee()) { +    const CXXRecordDecl *RD = type->getAsCXXRecordDecl(); +    if (RD && RD->hasNonTrivialDestructor()) { +      AggValueSlot Slot = CreateAggTemp(type, "agg.arg.tmp"); +      Slot.setExternallyDestructed(); +      EmitAggExpr(E, Slot); +      RValue RV = Slot.asRValue(); +      args.add(RV, type); + +      pushDestroy(EHCleanup, RV.getAggregateAddr(), type, destroyCXXObject, +                  /*useEHCleanupForArray*/ true); +      // This unreachable is a temporary marker which will be removed later. +      llvm::Instruction *IsActive = Builder.CreateUnreachable(); +      args.addArgCleanupDeactivation(EHStack.getInnermostEHScope(), IsActive); +      return; +    }    } -  if (hasAggregateEvaluationKind(type) && -      isa<ImplicitCastExpr>(E) && +  if (HasAggregateEvalKind && isa<ImplicitCastExpr>(E) &&        cast<CastExpr>(E)->getCastKind() == CK_LValueToRValue) {      LValue L = EmitLValue(cast<CastExpr>(E)->getSubExpr());      assert(L.isSimple()); -    args.add(L.asAggregateRValue(), type, /*NeedsCopy*/true); +    if (L.getAlignment() >= getContext().getTypeAlignInChars(type)) { +      args.add(L.asAggregateRValue(), type, /*NeedsCopy*/true); +    } else { +      // We can't represent a misaligned lvalue in the CallArgList, so copy +      // to an aligned temporary now. +      llvm::Value *tmp = CreateMemTemp(type); +      EmitAggregateCopy(tmp, L.getAddress(), type, L.isVolatile(), +                        L.getAlignment()); +      args.add(RValue::getAggregate(tmp), type); +    }      return;    } @@ -2127,7 +2189,7 @@ static void checkArgMatches(llvm::Value *Elt, unsigned &ArgNo,  }  void CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV, -                                       SmallVector<llvm::Value*,16> &Args, +                                       SmallVectorImpl<llvm::Value *> &Args,                                         llvm::FunctionType *IRFuncTy) {    if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {      unsigned NumElts = AT->getSize().getZExtValue(); @@ -2135,7 +2197,7 @@ void CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,      llvm::Value *Addr = RV.getAggregateAddr();      for (unsigned Elt = 0; Elt < NumElts; ++Elt) {        llvm::Value *EltAddr = Builder.CreateConstGEP2_32(Addr, 0, Elt); -      RValue EltRV = convertTempToRValue(EltAddr, EltTy); +      RValue EltRV = convertTempToRValue(EltAddr, EltTy, SourceLocation());        ExpandTypeToArgs(EltTy, EltRV, Args, IRFuncTy);      }    } else if (const RecordType *RT = Ty->getAs<RecordType>()) { @@ -2159,7 +2221,7 @@ void CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,          }        }        if (LargestFD) { -        RValue FldRV = EmitRValueForField(LV, LargestFD); +        RValue FldRV = EmitRValueForField(LV, LargestFD, SourceLocation());          ExpandTypeToArgs(LargestFD->getType(), FldRV, Args, IRFuncTy);        }      } else { @@ -2167,7 +2229,7 @@ void CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,             i != e; ++i) {          FieldDecl *FD = *i; -        RValue FldRV = EmitRValueForField(LV, FD); +        RValue FldRV = EmitRValueForField(LV, FD, SourceLocation());          ExpandTypeToArgs(FD->getType(), FldRV, Args, IRFuncTy);        }      } @@ -2394,6 +2456,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,      }    } +  if (!CallArgs.getCleanupsToDeactivate().empty()) +    deactivateArgCleanupsBeforeCall(*this, CallArgs); +    // If the callee is a bitcast of a function to a varargs pointer to function    // type, check to see if we can remove the bitcast.  This handles some cases    // with unprototyped functions. @@ -2482,7 +2547,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,    switch (RetAI.getKind()) {    case ABIArgInfo::Indirect: -    return convertTempToRValue(Args[0], RetTy); +    return convertTempToRValue(Args[0], RetTy, SourceLocation());    case ABIArgInfo::Ignore:      // If we are ignoring an argument that had a result, make sure to @@ -2540,7 +2605,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,      }      CreateCoercedStore(CI, StorePtr, DestIsVolatile, *this); -    return convertTempToRValue(DestPtr, RetTy); +    return convertTempToRValue(DestPtr, RetTy, SourceLocation());    }    case ABIArgInfo::Expand: diff --git a/lib/CodeGen/CGCall.h b/lib/CodeGen/CGCall.h index 85c3320ec0eef..532cb59c62e57 100644 --- a/lib/CodeGen/CGCall.h +++ b/lib/CodeGen/CGCall.h @@ -16,6 +16,7 @@  #define CLANG_CODEGEN_CGCALL_H  #include "CGValue.h" +#include "EHScopeStack.h"  #include "clang/AST/CanonicalType.h"  #include "clang/AST/Type.h"  #include "llvm/ADT/FoldingSet.h" @@ -67,6 +68,14 @@ namespace CodeGen {        llvm::Value *ToUse;      }; +    struct CallArgCleanup { +      EHScopeStack::stable_iterator Cleanup; + +      /// The "is active" insertion point.  This instruction is temporary and +      /// will be removed after insertion. +      llvm::Instruction *IsActiveIP; +    }; +      void add(RValue rvalue, QualType type, bool needscopy = false) {        push_back(CallArg(rvalue, type, needscopy));      } @@ -92,57 +101,25 @@ namespace CodeGen {      writeback_iterator writeback_begin() const { return Writebacks.begin(); }      writeback_iterator writeback_end() const { return Writebacks.end(); } -  private: -    SmallVector<Writeback, 1> Writebacks; -  }; - -  /// A class for recording the number of arguments that a function -  /// signature requires. -  class RequiredArgs { -    /// The number of required arguments, or ~0 if the signature does -    /// not permit optional arguments. -    unsigned NumRequired; -  public: -    enum All_t { All }; - -    RequiredArgs(All_t _) : NumRequired(~0U) {} -    explicit RequiredArgs(unsigned n) : NumRequired(n) { -      assert(n != ~0U); -    } - -    /// Compute the arguments required by the given formal prototype, -    /// given that there may be some additional, non-formal arguments -    /// in play. -    static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, -                                         unsigned additional) { -      if (!prototype->isVariadic()) return All; -      return RequiredArgs(prototype->getNumArgs() + additional); -    } - -    static RequiredArgs forPrototype(const FunctionProtoType *prototype) { -      return forPrototypePlus(prototype, 0); -    } - -    static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) { -      return forPrototype(prototype.getTypePtr()); +    void addArgCleanupDeactivation(EHScopeStack::stable_iterator Cleanup, +                                   llvm::Instruction *IsActiveIP) { +      CallArgCleanup ArgCleanup; +      ArgCleanup.Cleanup = Cleanup; +      ArgCleanup.IsActiveIP = IsActiveIP; +      CleanupsToDeactivate.push_back(ArgCleanup);      } -    static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype, -                                         unsigned additional) { -      return forPrototypePlus(prototype.getTypePtr(), additional); +    ArrayRef<CallArgCleanup> getCleanupsToDeactivate() const { +      return CleanupsToDeactivate;      } -    bool allowsOptionalArgs() const { return NumRequired != ~0U; } -    unsigned getNumRequiredArgs() const { -      assert(allowsOptionalArgs()); -      return NumRequired; -    } +  private: +    SmallVector<Writeback, 1> Writebacks; -    unsigned getOpaqueData() const { return NumRequired; } -    static RequiredArgs getFromOpaqueData(unsigned value) { -      if (value == ~0U) return All; -      return RequiredArgs(value); -    } +    /// Deactivate these cleanups immediately before making the call.  This +    /// is used to cleanup objects that are owned by the callee once the call +    /// occurs. +    SmallVector<CallArgCleanup, 1> CleanupsToDeactivate;    };    /// FunctionArgList - Type for representing both the decl and type @@ -151,137 +128,6 @@ namespace CodeGen {    class FunctionArgList : public SmallVector<const VarDecl*, 16> {    }; -  /// CGFunctionInfo - Class to encapsulate the information about a -  /// function definition. -  class CGFunctionInfo : public llvm::FoldingSetNode { -    struct ArgInfo { -      CanQualType type; -      ABIArgInfo info; -    }; - -    /// The LLVM::CallingConv to use for this function (as specified by the -    /// user). -    unsigned CallingConvention : 8; - -    /// The LLVM::CallingConv to actually use for this function, which may -    /// depend on the ABI. -    unsigned EffectiveCallingConvention : 8; - -    /// The clang::CallingConv that this was originally created with. -    unsigned ASTCallingConvention : 8; - -    /// Whether this function is noreturn. -    unsigned NoReturn : 1; - -    /// Whether this function is returns-retained. -    unsigned ReturnsRetained : 1; - -    /// How many arguments to pass inreg. -    unsigned HasRegParm : 1; -    unsigned RegParm : 4; - -    RequiredArgs Required; - -    unsigned NumArgs; -    ArgInfo *getArgsBuffer() { -      return reinterpret_cast<ArgInfo*>(this+1); -    } -    const ArgInfo *getArgsBuffer() const { -      return reinterpret_cast<const ArgInfo*>(this + 1); -    } - -    CGFunctionInfo() : Required(RequiredArgs::All) {} - -  public: -    static CGFunctionInfo *create(unsigned llvmCC, -                                  const FunctionType::ExtInfo &extInfo, -                                  CanQualType resultType, -                                  ArrayRef<CanQualType> argTypes, -                                  RequiredArgs required); - -    typedef const ArgInfo *const_arg_iterator; -    typedef ArgInfo *arg_iterator; - -    const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; } -    const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; } -    arg_iterator arg_begin() { return getArgsBuffer() + 1; } -    arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; } - -    unsigned  arg_size() const { return NumArgs; } - -    bool isVariadic() const { return Required.allowsOptionalArgs(); } -    RequiredArgs getRequiredArgs() const { return Required; } - -    bool isNoReturn() const { return NoReturn; } - -    /// In ARC, whether this function retains its return value.  This -    /// is not always reliable for call sites. -    bool isReturnsRetained() const { return ReturnsRetained; } - -    /// getASTCallingConvention() - Return the AST-specified calling -    /// convention. -    CallingConv getASTCallingConvention() const { -      return CallingConv(ASTCallingConvention); -    } - -    /// getCallingConvention - Return the user specified calling -    /// convention, which has been translated into an LLVM CC. -    unsigned getCallingConvention() const { return CallingConvention; } - -    /// getEffectiveCallingConvention - Return the actual calling convention to -    /// use, which may depend on the ABI. -    unsigned getEffectiveCallingConvention() const { -      return EffectiveCallingConvention; -    } -    void setEffectiveCallingConvention(unsigned Value) { -      EffectiveCallingConvention = Value; -    } - -    bool getHasRegParm() const { return HasRegParm; } -    unsigned getRegParm() const { return RegParm; } - -    FunctionType::ExtInfo getExtInfo() const { -      return FunctionType::ExtInfo(isNoReturn(), -                                   getHasRegParm(), getRegParm(), -                                   getASTCallingConvention(), -                                   isReturnsRetained()); -    } - -    CanQualType getReturnType() const { return getArgsBuffer()[0].type; } - -    ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; } -    const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; } - -    void Profile(llvm::FoldingSetNodeID &ID) { -      ID.AddInteger(getASTCallingConvention()); -      ID.AddBoolean(NoReturn); -      ID.AddBoolean(ReturnsRetained); -      ID.AddBoolean(HasRegParm); -      ID.AddInteger(RegParm); -      ID.AddInteger(Required.getOpaqueData()); -      getReturnType().Profile(ID); -      for (arg_iterator it = arg_begin(), ie = arg_end(); it != ie; ++it) -        it->type.Profile(ID); -    } -    static void Profile(llvm::FoldingSetNodeID &ID, -                        const FunctionType::ExtInfo &info, -                        RequiredArgs required, -                        CanQualType resultType, -                        ArrayRef<CanQualType> argTypes) { -      ID.AddInteger(info.getCC()); -      ID.AddBoolean(info.getNoReturn()); -      ID.AddBoolean(info.getProducesResult()); -      ID.AddBoolean(info.getHasRegParm()); -      ID.AddInteger(info.getRegParm()); -      ID.AddInteger(required.getOpaqueData()); -      resultType.Profile(ID); -      for (ArrayRef<CanQualType>::iterator -             i = argTypes.begin(), e = argTypes.end(); i != e; ++i) { -        i->Profile(ID); -      } -    } -  }; -      /// ReturnValueSlot - Contains the address where the return value of a     /// function can be stored, and whether the address is volatile or not.    class ReturnValueSlot { diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 3fd075701d039..4848d7565d40b 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -17,10 +17,12 @@  #include "CodeGenFunction.h"  #include "CGCXXABI.h"  #include "clang/AST/CXXInheritance.h" +#include "clang/AST/DeclTemplate.h"  #include "clang/AST/EvaluatedExprVisitor.h"  #include "clang/AST/RecordLayout.h"  #include "clang/AST/StmtCXX.h"  #include "clang/Basic/TargetBuiltins.h" +#include "clang/CodeGen/CGFunctionInfo.h"  #include "clang/Frontend/CodeGenOptions.h"  using namespace clang; @@ -198,7 +200,8 @@ CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value,    // Compute the virtual offset.    llvm::Value *VirtualOffset = 0;    if (VBase) { -    VirtualOffset = GetVirtualBaseClassOffset(Value, Derived, VBase); +    VirtualOffset = +      CGM.getCXXABI().GetVirtualBaseClassOffset(*this, Value, Derived, VBase);    }    // Apply both offsets. @@ -285,7 +288,7 @@ CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value,  llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD,                                                bool ForVirtualBase,                                                bool Delegating) { -  if (!CodeGenVTables::needsVTTParameter(GD)) { +  if (!CGM.getCXXABI().NeedsVTTParameter(GD)) {      // This constructor/destructor does not need a VTT parameter.      return 0;    } @@ -303,7 +306,7 @@ llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD,    } else if (RD == Base) {      // If the record matches the base, this is the complete ctor/dtor      // variant calling the base variant in a class with virtual bases. -    assert(!CodeGenVTables::needsVTTParameter(CurGD) && +    assert(!CGM.getCXXABI().NeedsVTTParameter(CurGD) &&             "doing no-op VTT offset in base dtor/ctor?");      assert(!ForVirtualBase && "Can't have same class as virtual base!");      SubVTTIndex = 0; @@ -318,7 +321,7 @@ llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD,      assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!");    } -  if (CodeGenVTables::needsVTTParameter(CurGD)) { +  if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) {      // A VTT parameter was passed to the constructor, use it.      VTT = LoadCXXVTT();      VTT = Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex); @@ -432,52 +435,45 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF,                                       unsigned Index) {    if (Index == ArrayIndexes.size()) {      LValue LV = LHS; -    { // Scope for Cleanups. -      CodeGenFunction::RunCleanupsScope Cleanups(CGF); - -      if (ArrayIndexVar) { -        // If we have an array index variable, load it and use it as an offset. -        // Then, increment the value. -        llvm::Value *Dest = LHS.getAddress(); -        llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar); -        Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress"); -        llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1); -        Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc"); -        CGF.Builder.CreateStore(Next, ArrayIndexVar);     - -        // Update the LValue. -        LV.setAddress(Dest); -        CharUnits Align = CGF.getContext().getTypeAlignInChars(T); -        LV.setAlignment(std::min(Align, LV.getAlignment())); -      } -      switch (CGF.getEvaluationKind(T)) { -      case TEK_Scalar: -        CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false); -        break; -      case TEK_Complex: -        CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true); -        break; -      case TEK_Aggregate: { -        AggValueSlot Slot = -          AggValueSlot::forLValue(LV, -                                  AggValueSlot::IsDestructed, -                                  AggValueSlot::DoesNotNeedGCBarriers, -                                  AggValueSlot::IsNotAliased); - -        CGF.EmitAggExpr(Init, Slot); -        break; -      } -      } +    if (ArrayIndexVar) { +      // If we have an array index variable, load it and use it as an offset. +      // Then, increment the value. +      llvm::Value *Dest = LHS.getAddress(); +      llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar); +      Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress"); +      llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1); +      Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc"); +      CGF.Builder.CreateStore(Next, ArrayIndexVar); + +      // Update the LValue. +      LV.setAddress(Dest); +      CharUnits Align = CGF.getContext().getTypeAlignInChars(T); +      LV.setAlignment(std::min(Align, LV.getAlignment()));      } -    // Now, outside of the initializer cleanup scope, destroy the backing array -    // for a std::initializer_list member. -    CGF.MaybeEmitStdInitializerListCleanup(LV.getAddress(), Init); +    switch (CGF.getEvaluationKind(T)) { +    case TEK_Scalar: +      CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false); +      break; +    case TEK_Complex: +      CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true); +      break; +    case TEK_Aggregate: { +      AggValueSlot Slot = +        AggValueSlot::forLValue(LV, +                                AggValueSlot::IsDestructed, +                                AggValueSlot::DoesNotNeedGCBarriers, +                                AggValueSlot::IsNotAliased); + +      CGF.EmitAggExpr(Init, Slot); +      break; +    } +    }      return;    } -   +    const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T);    assert(Array && "Array initialization without the array type?");    llvm::Value *IndexVar @@ -511,16 +507,12 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF,    CGF.EmitBlock(ForBody);    llvm::BasicBlock *ContinueBlock = CGF.createBasicBlock("for.inc"); -   -  { -    CodeGenFunction::RunCleanupsScope Cleanups(CGF); -     -    // Inside the loop body recurse to emit the inner loop or, eventually, the -    // constructor call. -    EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar, -                             Array->getElementType(), ArrayIndexes, Index + 1); -  } -   + +  // Inside the loop body recurse to emit the inner loop or, eventually, the +  // constructor call. +  EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar, +                           Array->getElementType(), ArrayIndexes, Index + 1); +    CGF.EmitBlock(ContinueBlock);    // Emit the increment of the loop counter. @@ -573,7 +565,7 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,    // in the AST, we could generalize it more easily.    const ConstantArrayType *Array      = CGF.getContext().getAsConstantArrayType(FieldType); -  if (Array && Constructor->isImplicitlyDefined() && +  if (Array && Constructor->isDefaulted() &&        Constructor->isCopyOrMoveConstructor()) {      QualType BaseElementTy = CGF.getContext().getBaseElementType(Array);      CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit()); @@ -713,7 +705,7 @@ void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) {        CGM.getTarget().getCXXABI().hasConstructorVariants()) {      if (CGDebugInfo *DI = getDebugInfo())         DI->EmitLocation(Builder, Ctor->getLocEnd()); -    EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args); +    EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args, Ctor->getLocEnd());      return;    } @@ -725,7 +717,7 @@ void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) {    if (IsTryBody)      EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); -  EHScopeStack::stable_iterator CleanupDepth = EHStack.stable_begin(); +  RunCleanupsScope RunCleanups(*this);    // TODO: in restricted cases, we can emit the vbase initializers of    // a complete ctor and then delegate to the base ctor. @@ -744,13 +736,36 @@ void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) {    // initializers, which includes (along the exceptional path) the    // destructors for those members and bases that were fully    // constructed. -  PopCleanupBlocks(CleanupDepth); +  RunCleanups.ForceCleanup();    if (IsTryBody)      ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true);  }  namespace { +  /// RAII object to indicate that codegen is copying the value representation +  /// instead of the object representation. Useful when copying a struct or +  /// class which has uninitialized members and we're only performing +  /// lvalue-to-rvalue conversion on the object but not its members. +  class CopyingValueRepresentation { +  public: +    explicit CopyingValueRepresentation(CodeGenFunction &CGF) +        : CGF(CGF), SO(*CGF.SanOpts), OldSanOpts(CGF.SanOpts) { +      SO.Bool = false; +      SO.Enum = false; +      CGF.SanOpts = &SO; +    } +    ~CopyingValueRepresentation() { +      CGF.SanOpts = OldSanOpts; +    } +  private: +    CodeGenFunction &CGF; +    SanitizerOptions SO; +    const SanitizerOptions *OldSanOpts; +  }; +} + +namespace {    class FieldMemcpyizer {    public:      FieldMemcpyizer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, @@ -859,8 +874,12 @@ namespace {        }      void addNextField(FieldDecl *F) { -      assert(F->getFieldIndex() == LastAddedFieldIndex + 1 && -             "Cannot aggregate non-contiguous fields."); +      // For the most part, the following invariant will hold: +      //   F->getFieldIndex() == LastAddedFieldIndex + 1 +      // The one exception is that Sema won't add a copy-initializer for an +      // unnamed bitfield, which will show up here as a gap in the sequence. +      assert(F->getFieldIndex() >= LastAddedFieldIndex + 1 && +             "Cannot aggregate fields out of order.");        LastAddedFieldIndex = F->getFieldIndex();        // The 'first' and 'last' fields are chosen by offset, rather than field @@ -891,7 +910,7 @@ namespace {      /// constructor.       static const VarDecl* getTrivialCopySource(const CXXConstructorDecl *CD,                                                 FunctionArgList &Args) { -      if (CD->isCopyOrMoveConstructor() && CD->isImplicitlyDefined()) +      if (CD->isCopyOrMoveConstructor() && CD->isDefaulted())          return Args[Args.size() - 1];        return 0;       } @@ -925,7 +944,7 @@ namespace {                            FunctionArgList &Args)        : FieldMemcpyizer(CGF, CD->getParent(), getTrivialCopySource(CD, Args)),          ConstructorDecl(CD), -        MemcpyableCtor(CD->isImplicitlyDefined() && +        MemcpyableCtor(CD->isDefaulted() &&                         CD->isCopyOrMoveConstructor() &&                         CGF.getLangOpts().getGC() == LangOptions::NonGC),          Args(Args) { } @@ -945,9 +964,10 @@ namespace {        if (AggregatedInits.size() <= 1) {          // This memcpy is too small to be worthwhile. Fall back on default          // codegen. -        for (unsigned i = 0; i < AggregatedInits.size(); ++i) { +        if (!AggregatedInits.empty()) { +          CopyingValueRepresentation CVR(CGF);            EmitMemberInitializer(CGF, ConstructorDecl->getParent(), -                                AggregatedInits[i], ConstructorDecl, Args); +                                AggregatedInits[0], ConstructorDecl, Args);          }          reset();          return; @@ -986,8 +1006,8 @@ namespace {    private:      // Returns the memcpyable field copied by the given statement, if one -    // exists. Otherwise r -    FieldDecl* getMemcpyableField(Stmt *S) { +    // exists. Otherwise returns null. +    FieldDecl *getMemcpyableField(Stmt *S) {        if (!AssignmentsMemcpyable)          return 0;        if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) { @@ -1081,8 +1101,10 @@ namespace {      void emitAggregatedStmts() {        if (AggregatedStmts.size() <= 1) { -        for (unsigned i = 0; i < AggregatedStmts.size(); ++i) -          CGF.EmitStmt(AggregatedStmts[i]); +        if (!AggregatedStmts.empty()) { +          CopyingValueRepresentation CVR(CGF); +          CGF.EmitStmt(AggregatedStmts[0]); +        }          reset();        } @@ -1115,7 +1137,8 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,        !CGM.getTarget().getCXXABI().hasConstructorVariants()) {      // The ABIs that don't have constructor variants need to put a branch      // before the virtual base initialization code. -    BaseCtorContinueBB = CGM.getCXXABI().EmitCtorCompleteObjectHandler(*this); +    BaseCtorContinueBB = +      CGM.getCXXABI().EmitCtorCompleteObjectHandler(*this, ClassDecl);      assert(BaseCtorContinueBB);    } @@ -1270,16 +1293,19 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {    // If this is the complete variant, just invoke the base variant;    // the epilogue will destruct the virtual bases.  But we can't do    // this optimization if the body is a function-try-block, because -  // we'd introduce *two* handler blocks. +  // we'd introduce *two* handler blocks.  In the Microsoft ABI, we  +  // always delegate because we might not have a definition in this TU.    switch (DtorType) {    case Dtor_Deleting: llvm_unreachable("already handled deleting case");    case Dtor_Complete: +    assert((Body || getTarget().getCXXABI().isMicrosoft()) && +           "can't emit a dtor without a body for non-Microsoft ABIs"); +      // Enter the cleanup scopes for virtual bases.      EnterDtorCleanups(Dtor, Dtor_Complete); -    if (!isTryBody && -        CGM.getTarget().getCXXABI().hasDestructorVariants()) { +    if (!isTryBody) {        EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false,                              /*Delegating=*/false, LoadCXXThis());        break; @@ -1287,6 +1313,8 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {      // Fallthrough: act like we're in the base variant.    case Dtor_Base: +    assert(Body); +      // Enter the cleanup scopes for fields and non-virtual bases.      EnterDtorCleanups(Dtor, Dtor_Base); @@ -1635,17 +1663,6 @@ CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,                                          llvm::Value *This,                                          CallExpr::const_arg_iterator ArgBeg,                                          CallExpr::const_arg_iterator ArgEnd) { - -  CGDebugInfo *DI = getDebugInfo(); -  if (DI && -      CGM.getCodeGenOpts().getDebugInfo() == CodeGenOptions::LimitedDebugInfo) { -    // If debug info for this class has not been emitted then this is the -    // right time to do so. -    const CXXRecordDecl *Parent = D->getParent(); -    DI->getOrCreateRecordType(CGM.getContext().getTypeDeclType(Parent), -                              Parent->getLocation()); -  } -    // If this is a trivial constructor, just emit what's needed.    if (D->isTrivial()) {      if (ArgBeg == ArgEnd) { @@ -1667,11 +1684,8 @@ CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,    }    // Non-trivial constructors are handled in an ABI-specific manner. -  llvm::Value *Callee = CGM.getCXXABI().EmitConstructorCall(*this, D, Type, -                            ForVirtualBase, Delegating, This, ArgBeg, ArgEnd); -  if (CGM.getCXXABI().HasThisReturn(CurGD) && -      CGM.getCXXABI().HasThisReturn(GlobalDecl(D, Type))) -     CalleeWithThisReturn = Callee; +  CGM.getCXXABI().EmitConstructorCall(*this, D, Type, ForVirtualBase, +                                      Delegating, This, ArgBeg, ArgEnd);  }  void @@ -1686,8 +1700,7 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,      EmitAggregateCopy(This, Src, (*ArgBeg)->getType());      return;    } -  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D,  -                                                    clang::Ctor_Complete); +  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, clang::Ctor_Complete);    assert(D->isInstance() &&           "Trying to emit a member call expr on a static method!"); @@ -1730,7 +1743,8 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,  void  CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,                                                  CXXCtorType CtorType, -                                                const FunctionArgList &Args) { +                                                const FunctionArgList &Args, +                                                SourceLocation Loc) {    CallArgList DelegateArgs;    FunctionArgList::const_iterator I = Args.begin(), E = Args.end(); @@ -1747,7 +1761,7 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,      QualType VoidPP = getContext().getPointerType(getContext().VoidPtrTy);      DelegateArgs.add(RValue::get(VTT), VoidPP); -    if (CodeGenVTables::needsVTTParameter(CurGD)) { +    if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) {        assert(I != E && "cannot skip vtt parameter, already done with args");        assert((*I)->getType() == VoidPP && "skipping parameter not of vtt type");        ++I; @@ -1757,15 +1771,13 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,    // Explicit arguments.    for (; I != E; ++I) {      const VarDecl *param = *I; -    EmitDelegateCallArg(DelegateArgs, param); +    // FIXME: per-argument source location +    EmitDelegateCallArg(DelegateArgs, param, Loc);    }    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(Ctor, CtorType);    EmitCall(CGM.getTypes().arrangeCXXConstructorDeclaration(Ctor, CtorType),             Callee, ReturnValueSlot(), DelegateArgs, Ctor); -  if (CGM.getCXXABI().HasThisReturn(CurGD) && -      CGM.getCXXABI().HasThisReturn(GlobalDecl(Ctor, CtorType))) -     CalleeWithThisReturn = Callee;  }  namespace { @@ -1818,8 +1830,8 @@ void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,                                              bool ForVirtualBase,                                              bool Delegating,                                              llvm::Value *This) { -  llvm::Value *VTT = GetVTTParameter(GlobalDecl(DD, Type), -                                     ForVirtualBase, Delegating); +  GlobalDecl GD(DD, Type); +  llvm::Value *VTT = GetVTTParameter(GD, ForVirtualBase, Delegating);    llvm::Value *Callee = 0;    if (getLangOpts().AppleKext)      Callee = BuildAppleKextVirtualDestructorCall(DD, Type,  @@ -1827,14 +1839,14 @@ void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,    if (!Callee)      Callee = CGM.GetAddrOfCXXDestructor(DD, Type); -   + +  if (DD->isVirtual()) +    This = CGM.getCXXABI().adjustThisArgumentForVirtualCall(*this, GD, This); +    // FIXME: Provide a source location here.    EmitCXXMemberCall(DD, SourceLocation(), Callee, ReturnValueSlot(), This,                      VTT, getContext().getPointerType(getContext().VoidPtrTy),                      0, 0); -  if (CGM.getCXXABI().HasThisReturn(CurGD) && -      CGM.getCXXABI().HasThisReturn(GlobalDecl(DD, Type))) -     CalleeWithThisReturn = Callee;  }  namespace { @@ -1868,69 +1880,30 @@ void CodeGenFunction::PushDestructorCleanup(QualType T, llvm::Value *Addr) {    PushDestructorCleanup(D, Addr);  } -llvm::Value * -CodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This, -                                           const CXXRecordDecl *ClassDecl, -                                           const CXXRecordDecl *BaseClassDecl) { -  llvm::Value *VTablePtr = GetVTablePtr(This, Int8PtrTy); -  CharUnits VBaseOffsetOffset =  -    CGM.getVTableContext().getVirtualBaseOffsetOffset(ClassDecl, BaseClassDecl); -   -  llvm::Value *VBaseOffsetPtr =  -    Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset.getQuantity(),  -                               "vbase.offset.ptr"); -  llvm::Type *PtrDiffTy =  -    ConvertType(getContext().getPointerDiffType()); -   -  VBaseOffsetPtr = Builder.CreateBitCast(VBaseOffsetPtr,  -                                         PtrDiffTy->getPointerTo()); -                                          -  llvm::Value *VBaseOffset = Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset"); -   -  return VBaseOffset; -} -  void  CodeGenFunction::InitializeVTablePointer(BaseSubobject Base,                                            const CXXRecordDecl *NearestVBase,                                           CharUnits OffsetFromNearestVBase, -                                         llvm::Constant *VTable,                                           const CXXRecordDecl *VTableClass) { -  const CXXRecordDecl *RD = Base.getBase(); -    // Compute the address point. -  llvm::Value *VTableAddressPoint; - -  // Check if we need to use a vtable from the VTT. -  if (CodeGenVTables::needsVTTParameter(CurGD) && -      (RD->getNumVBases() || NearestVBase)) { -    // Get the secondary vpointer index. -    uint64_t VirtualPointerIndex =  -     CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base); -     -    /// Load the VTT. -    llvm::Value *VTT = LoadCXXVTT(); -    if (VirtualPointerIndex) -      VTT = Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex); - -    // And load the address point from the VTT. -    VTableAddressPoint = Builder.CreateLoad(VTT); -  } else { -    uint64_t AddressPoint = -      CGM.getVTableContext().getVTableLayout(VTableClass).getAddressPoint(Base); -    VTableAddressPoint = -      Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint); -  } +  bool NeedsVirtualOffset; +  llvm::Value *VTableAddressPoint = +      CGM.getCXXABI().getVTableAddressPointInStructor( +          *this, VTableClass, Base, NearestVBase, NeedsVirtualOffset); +  if (!VTableAddressPoint) +    return;    // Compute where to store the address point.    llvm::Value *VirtualOffset = 0;    CharUnits NonVirtualOffset = CharUnits::Zero(); -  if (CodeGenVTables::needsVTTParameter(CurGD) && NearestVBase) { +  if (NeedsVirtualOffset) {      // We need to use the virtual base offset offset because the virtual base      // might have a different offset in the most derived class. -    VirtualOffset = GetVirtualBaseClassOffset(LoadCXXThis(), VTableClass,  -                                              NearestVBase); +    VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(*this, +                                                              LoadCXXThis(), +                                                              VTableClass, +                                                              NearestVBase);      NonVirtualOffset = OffsetFromNearestVBase;    } else {      // We can just use the base offset in the complete class. @@ -1958,7 +1931,6 @@ CodeGenFunction::InitializeVTablePointers(BaseSubobject Base,                                            const CXXRecordDecl *NearestVBase,                                            CharUnits OffsetFromNearestVBase,                                            bool BaseIsNonVirtualPrimaryBase, -                                          llvm::Constant *VTable,                                            const CXXRecordDecl *VTableClass,                                            VisitedVirtualBasesSetTy& VBases) {    // If this base is a non-virtual primary base the address point has already @@ -1966,7 +1938,7 @@ CodeGenFunction::InitializeVTablePointers(BaseSubobject Base,    if (!BaseIsNonVirtualPrimaryBase) {      // Initialize the vtable pointer for this base.      InitializeVTablePointer(Base, NearestVBase, OffsetFromNearestVBase, -                            VTable, VTableClass); +                            VTableClass);    }    const CXXRecordDecl *RD = Base.getBase(); @@ -2009,7 +1981,7 @@ CodeGenFunction::InitializeVTablePointers(BaseSubobject Base,                               I->isVirtual() ? BaseDecl : NearestVBase,                               BaseOffsetFromNearestVBase,                               BaseDeclIsNonVirtualPrimaryBase,  -                             VTable, VTableClass, VBases); +                             VTableClass, VBases);    }  } @@ -2018,16 +1990,15 @@ void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) {    if (!RD->isDynamicClass())      return; -  // Get the VTable. -  llvm::Constant *VTable = CGM.getVTables().GetAddrOfVTable(RD); -    // Initialize the vtable pointers for this class and all of its bases.    VisitedVirtualBasesSetTy VBases;    InitializeVTablePointers(BaseSubobject(RD, CharUnits::Zero()),                              /*NearestVBase=*/0,                              /*OffsetFromNearestVBase=*/CharUnits::Zero(), -                           /*BaseIsNonVirtualPrimaryBase=*/false,  -                           VTable, RD, VBases); +                           /*BaseIsNonVirtualPrimaryBase=*/false, RD, VBases); + +  if (RD->getNumVBases()) +    CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*this, RD);  }  llvm::Value *CodeGenFunction::GetVTablePtr(llvm::Value *This, @@ -2038,29 +2009,6 @@ llvm::Value *CodeGenFunction::GetVTablePtr(llvm::Value *This,    return VTable;  } -static const CXXRecordDecl *getMostDerivedClassDecl(const Expr *Base) { -  const Expr *E = Base; -   -  while (true) { -    E = E->IgnoreParens(); -    if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { -      if (CE->getCastKind() == CK_DerivedToBase ||  -          CE->getCastKind() == CK_UncheckedDerivedToBase || -          CE->getCastKind() == CK_NoOp) { -        E = CE->getSubExpr(); -        continue; -      } -    } - -    break; -  } - -  QualType DerivedType = E->getType(); -  if (const PointerType *PTy = DerivedType->getAs<PointerType>()) -    DerivedType = PTy->getPointeeType(); - -  return cast<CXXRecordDecl>(DerivedType->castAs<RecordType>()->getDecl()); -}  // FIXME: Ideally Expr::IgnoreParenNoopCasts should do this, but it doesn't do  // quite what we want. @@ -2087,10 +2035,14 @@ static const Expr *skipNoOpCastsAndParens(const Expr *E) {    }  } -/// canDevirtualizeMemberFunctionCall - Checks whether the given virtual member -/// function call on the given expr can be devirtualized. -static bool canDevirtualizeMemberFunctionCall(const Expr *Base,  -                                              const CXXMethodDecl *MD) { +bool +CodeGenFunction::CanDevirtualizeMemberFunctionCall(const Expr *Base, +                                                   const CXXMethodDecl *MD) { +  // When building with -fapple-kext, all calls must go through the vtable since +  // the kernel linker can do runtime patching of vtables. +  if (getLangOpts().AppleKext) +    return false; +    // If the most derived class is marked final, we know that no subclass can    // override this member function and so we can devirtualize it. For example:    // @@ -2101,7 +2053,7 @@ static bool canDevirtualizeMemberFunctionCall(const Expr *Base,    //   b->f();    // }    // -  const CXXRecordDecl *MostDerivedClassDecl = getMostDerivedClassDecl(Base); +  const CXXRecordDecl *MostDerivedClassDecl = Base->getBestDynamicClassType();    if (MostDerivedClassDecl->hasAttr<FinalAttr>())      return true; @@ -2124,7 +2076,14 @@ static bool canDevirtualizeMemberFunctionCall(const Expr *Base,      return false;    } -   + +  // We can devirtualize calls on an object accessed by a class member access +  // expression, since by C++11 [basic.life]p6 we know that it can't refer to +  // a derived class object constructed in the same location. +  if (const MemberExpr *ME = dyn_cast<MemberExpr>(Base)) +    if (const ValueDecl *VD = dyn_cast<ValueDecl>(ME->getMemberDecl())) +      return VD->getType()->isRecordType(); +    // We can always devirtualize calls on temporary object expressions.    if (isa<CXXConstructExpr>(Base))      return true; @@ -2141,20 +2100,6 @@ static bool canDevirtualizeMemberFunctionCall(const Expr *Base,    return false;  } -static bool UseVirtualCall(ASTContext &Context, -                           const CXXOperatorCallExpr *CE, -                           const CXXMethodDecl *MD) { -  if (!MD->isVirtual()) -    return false; -   -  // When building with -fapple-kext, all calls must go through the vtable since -  // the kernel linker can do runtime patching of vtables. -  if (Context.getLangOpts().AppleKext) -    return true; - -  return !canDevirtualizeMemberFunctionCall(CE->getArg(0), MD); -} -  llvm::Value *  CodeGenFunction::EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E,                                               const CXXMethodDecl *MD, @@ -2163,20 +2108,15 @@ CodeGenFunction::EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E,      CGM.getTypes().GetFunctionType(                               CGM.getTypes().arrangeCXXMethodDeclaration(MD)); -  if (UseVirtualCall(getContext(), E, MD)) -    return BuildVirtualCall(MD, This, fnType); +  if (MD->isVirtual() && !CanDevirtualizeMemberFunctionCall(E->getArg(0), MD)) +    return CGM.getCXXABI().getVirtualFunctionPointer(*this, MD, This, fnType);    return CGM.GetAddrOfFunction(MD, fnType);  } -void CodeGenFunction::EmitForwardingCallToLambda(const CXXRecordDecl *lambda, -                                                 CallArgList &callArgs) { -  // Lookup the call operator -  DeclarationName operatorName -    = getContext().DeclarationNames.getCXXOperatorName(OO_Call); -  CXXMethodDecl *callOperator = -    cast<CXXMethodDecl>(lambda->lookup(operatorName).front()); - +void CodeGenFunction::EmitForwardingCallToLambda( +                                      const CXXMethodDecl *callOperator, +                                      CallArgList &callArgs) {    // Get the address of the call operator.    const CGFunctionInfo &calleeFnInfo =      CGM.getTypes().arrangeCXXMethodDeclaration(callOperator); @@ -2225,10 +2165,11 @@ void CodeGenFunction::EmitLambdaBlockInvokeBody() {    for (BlockDecl::param_const_iterator I = BD->param_begin(),         E = BD->param_end(); I != E; ++I) {      ParmVarDecl *param = *I; -    EmitDelegateCallArg(CallArgs, param); +    EmitDelegateCallArg(CallArgs, param, param->getLocStart());    } - -  EmitForwardingCallToLambda(Lambda, CallArgs); +  assert(!Lambda->isGenericLambda() &&  +            "generic lambda interconversion to block not implemented"); +  EmitForwardingCallToLambda(Lambda->getLambdaCallOperator(), CallArgs);  }  void CodeGenFunction::EmitLambdaToBlockPointerBody(FunctionArgList &Args) { @@ -2239,7 +2180,7 @@ void CodeGenFunction::EmitLambdaToBlockPointerBody(FunctionArgList &Args) {      return;    } -  EmitFunctionBody(Args); +  EmitFunctionBody(Args, cast<FunctionDecl>(CurGD.getDecl())->getBody());  }  void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) { @@ -2256,10 +2197,22 @@ void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) {    for (FunctionDecl::param_const_iterator I = MD->param_begin(),         E = MD->param_end(); I != E; ++I) {      ParmVarDecl *param = *I; -    EmitDelegateCallArg(CallArgs, param); +    EmitDelegateCallArg(CallArgs, param, param->getLocStart());    } - -  EmitForwardingCallToLambda(Lambda, CallArgs); +  const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator(); +  // For a generic lambda, find the corresponding call operator specialization +  // to which the call to the static-invoker shall be forwarded. +  if (Lambda->isGenericLambda()) { +    assert(MD->isFunctionTemplateSpecialization()); +    const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs(); +    FunctionTemplateDecl *CallOpTemplate = CallOp->getDescribedFunctionTemplate(); +    void *InsertPos = 0; +    FunctionDecl *CorrespondingCallOpSpecialization =  +        CallOpTemplate->findSpecialization(TAL->data(), TAL->size(), InsertPos);  +    assert(CorrespondingCallOpSpecialization); +    CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization); +  } +  EmitForwardingCallToLambda(CallOp, CallArgs);  }  void CodeGenFunction::EmitLambdaStaticInvokeFunction(const CXXMethodDecl *MD) { diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp index ba6b56c2676fa..65de4d498d1a3 100644 --- a/lib/CodeGen/CGCleanup.cpp +++ b/lib/CodeGen/CGCleanup.cpp @@ -17,8 +17,8 @@  //  //===----------------------------------------------------------------------===// -#include "CodeGenFunction.h"  #include "CGCleanup.h" +#include "CodeGenFunction.h"  using namespace clang;  using namespace CodeGen; @@ -371,8 +371,7 @@ void CodeGenFunction::ResolveBranchFixups(llvm::BasicBlock *Block) {  }  /// Pops cleanup blocks until the given savepoint is reached. -void CodeGenFunction::PopCleanupBlocks(EHScopeStack::stable_iterator Old, -                                       SourceLocation EHLoc) { +void CodeGenFunction::PopCleanupBlocks(EHScopeStack::stable_iterator Old) {    assert(Old.isValid());    while (EHStack.stable_begin() != Old) { @@ -384,8 +383,35 @@ void CodeGenFunction::PopCleanupBlocks(EHScopeStack::stable_iterator Old,      bool FallThroughIsBranchThrough =        Old.strictlyEncloses(Scope.getEnclosingNormalCleanup()); -    PopCleanupBlock(FallThroughIsBranchThrough, EHLoc); +    PopCleanupBlock(FallThroughIsBranchThrough); +  } +} + +/// Pops cleanup blocks until the given savepoint is reached, then add the +/// cleanups from the given savepoint in the lifetime-extended cleanups stack. +void +CodeGenFunction::PopCleanupBlocks(EHScopeStack::stable_iterator Old, +                                  size_t OldLifetimeExtendedSize) { +  PopCleanupBlocks(Old); + +  // Move our deferred cleanups onto the EH stack. +  for (size_t I = OldLifetimeExtendedSize, +              E = LifetimeExtendedCleanupStack.size(); I != E; /**/) { +    // Alignment should be guaranteed by the vptrs in the individual cleanups. +    assert((I % llvm::alignOf<LifetimeExtendedCleanupHeader>() == 0) && +           "misaligned cleanup stack entry"); + +    LifetimeExtendedCleanupHeader &Header = +        reinterpret_cast<LifetimeExtendedCleanupHeader&>( +            LifetimeExtendedCleanupStack[I]); +    I += sizeof(Header); + +    EHStack.pushCopyOfCleanup(Header.getKind(), +                              &LifetimeExtendedCleanupStack[I], +                              Header.getSize()); +    I += Header.getSize();    } +  LifetimeExtendedCleanupStack.resize(OldLifetimeExtendedSize);  }  static llvm::BasicBlock *CreateNormalEntry(CodeGenFunction &CGF, @@ -533,8 +559,7 @@ static void destroyOptimisticNormalEntry(CodeGenFunction &CGF,  /// Pops a cleanup block.  If the block includes a normal cleanup, the  /// current insertion point is threaded through the cleanup, as are  /// any branch fixups on the cleanup. -void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough, -                                      SourceLocation EHLoc) { +void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {    assert(!EHStack.empty() && "cleanup stack is empty!");    assert(isa<EHCleanupScope>(*EHStack.begin()) && "top not a cleanup!");    EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.begin()); @@ -836,7 +861,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough,    // Emit the EH cleanup if required.    if (RequiresEHCleanup) {      if (CGDebugInfo *DI = getDebugInfo()) -      DI->EmitLocation(Builder, EHLoc); +      DI->EmitLocation(Builder, CurEHLocation);      CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP(); diff --git a/lib/CodeGen/CGCleanup.h b/lib/CodeGen/CGCleanup.h index d8dbe41bf0f38..1bd6bba523fbf 100644 --- a/lib/CodeGen/CGCleanup.h +++ b/lib/CodeGen/CGCleanup.h @@ -14,13 +14,15 @@  #ifndef CLANG_CODEGEN_CGCLEANUP_H  #define CLANG_CODEGEN_CGCLEANUP_H -/// EHScopeStack is defined in CodeGenFunction.h, but its -/// implementation is in this file and in CGCleanup.cpp. -#include "CodeGenFunction.h" +#include "EHScopeStack.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h"  namespace llvm { -  class Value; -  class BasicBlock; +class BasicBlock; +class Value; +class ConstantInt; +class AllocaInst;  }  namespace clang { diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index ddcb931e46c51..fcb26f0da6153 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -13,6 +13,7 @@  #include "CGDebugInfo.h"  #include "CGBlocks.h" +#include "CGCXXABI.h"  #include "CGObjCRuntime.h"  #include "CodeGenFunction.h"  #include "CodeGenModule.h" @@ -36,12 +37,13 @@  #include "llvm/IR/Module.h"  #include "llvm/Support/Dwarf.h"  #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h"
  using namespace clang;  using namespace clang::CodeGen;  CGDebugInfo::CGDebugInfo(CodeGenModule &CGM) -  : CGM(CGM), DBuilder(CGM.getModule()), -    BlockLiteralGenericSet(false) { +    : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()), +      DBuilder(CGM.getModule()) {    CreateCompileUnit();  } @@ -50,9 +52,54 @@ CGDebugInfo::~CGDebugInfo() {           "Region stack mismatch, stack not empty!");  } + +NoLocation::NoLocation(CodeGenFunction &CGF, CGBuilderTy &B) +  : DI(CGF.getDebugInfo()), Builder(B) { +  if (DI) { +    SavedLoc = DI->getLocation(); +    DI->CurLoc = SourceLocation(); +    Builder.SetCurrentDebugLocation(llvm::DebugLoc()); +  } +} + +NoLocation::~NoLocation() { +  if (DI) { +    assert(Builder.getCurrentDebugLocation().isUnknown()); +    DI->CurLoc = SavedLoc; +  } +} + +ArtificialLocation::ArtificialLocation(CodeGenFunction &CGF, CGBuilderTy &B) +  : DI(CGF.getDebugInfo()), Builder(B) { +  if (DI) { +    SavedLoc = DI->getLocation(); +    DI->CurLoc = SourceLocation(); +    Builder.SetCurrentDebugLocation(llvm::DebugLoc()); +  } +} + +void ArtificialLocation::Emit() { +  if (DI) { +    // Sync the Builder. +    DI->EmitLocation(Builder, SavedLoc); +    DI->CurLoc = SourceLocation(); +    // Construct a location that has a valid scope, but no line info. +    assert(!DI->LexicalBlockStack.empty()); +    llvm::DIDescriptor Scope(DI->LexicalBlockStack.back()); +    Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(0, 0, Scope)); +  } +} + +ArtificialLocation::~ArtificialLocation() { +  if (DI) { +    assert(Builder.getCurrentDebugLocation().getLine() == 0); +    DI->CurLoc = SavedLoc; +  } +} +  void CGDebugInfo::setLocation(SourceLocation Loc) {    // If the new location isn't valid return. -  if (!Loc.isValid()) return; +  if (Loc.isInvalid()) return;    CurLoc = CGM.getContext().getSourceManager().getExpansionLoc(Loc); @@ -112,7 +159,7 @@ llvm::DIScope CGDebugInfo::getContextDescriptor(const Decl *Context) {  }  /// getFunctionName - Get function name for the given FunctionDecl. If the -/// name is constructred on demand (e.g. C++ destructor) then the name +/// name is constructed on demand (e.g. C++ destructor) then the name  /// is stored on the side.  StringRef CGDebugInfo::getFunctionName(const FunctionDecl *FD) {    assert (FD && "Invalid FunctionDecl!"); @@ -138,10 +185,7 @@ StringRef CGDebugInfo::getFunctionName(const FunctionDecl *FD) {    }    // Copy this name on the side and use its reference. -  OS.flush(); -  char *StrPtr = DebugInfoNames.Allocate<char>(NS.size()); -  memcpy(StrPtr, NS.data(), NS.size()); -  return StringRef(StrPtr, NS.size()); +  return internString(OS.str());  }  StringRef CGDebugInfo::getObjCMethodName(const ObjCMethodDecl *OMD) { @@ -149,35 +193,37 @@ StringRef CGDebugInfo::getObjCMethodName(const ObjCMethodDecl *OMD) {    llvm::raw_svector_ostream OS(MethodName);    OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';    const DeclContext *DC = OMD->getDeclContext(); -  if (const ObjCImplementationDecl *OID =  +  if (const ObjCImplementationDecl *OID =        dyn_cast<const ObjCImplementationDecl>(DC)) {       OS << OID->getName(); -  } else if (const ObjCInterfaceDecl *OID =  +  } else if (const ObjCInterfaceDecl *OID =               dyn_cast<const ObjCInterfaceDecl>(DC)) {        OS << OID->getName(); -  } else if (const ObjCCategoryImplDecl *OCD =  +  } else if (const ObjCCategoryImplDecl *OCD =               dyn_cast<const ObjCCategoryImplDecl>(DC)){        OS << ((const NamedDecl *)OCD)->getIdentifier()->getNameStart() << '(' <<            OCD->getIdentifier()->getNameStart() << ')'; +  } else if (isa<ObjCProtocolDecl>(DC)) { +    // We can extract the type of the class from the self pointer. +    if (ImplicitParamDecl* SelfDecl = OMD->getSelfDecl()) { +      QualType ClassTy = +        cast<ObjCObjectPointerType>(SelfDecl->getType())->getPointeeType(); +      ClassTy.print(OS, PrintingPolicy(LangOptions())); +    }    }    OS << ' ' << OMD->getSelector().getAsString() << ']'; -  char *StrPtr = DebugInfoNames.Allocate<char>(OS.tell()); -  memcpy(StrPtr, MethodName.begin(), OS.tell()); -  return StringRef(StrPtr, OS.tell()); +  return internString(OS.str());  }  /// getSelectorName - Return selector name. This is used for debugging  /// info.  StringRef CGDebugInfo::getSelectorName(Selector S) { -  const std::string &SName = S.getAsString(); -  char *StrPtr = DebugInfoNames.Allocate<char>(SName.size()); -  memcpy(StrPtr, SName.data(), SName.size()); -  return StringRef(StrPtr, SName.size()); +  return internString(S.getAsString());  }  /// getClassName - Get class name including template argument list. -StringRef  +StringRef  CGDebugInfo::getClassName(const RecordDecl *RD) {    const ClassTemplateSpecializationDecl *Spec      = dyn_cast<ClassTemplateSpecializationDecl>(RD); @@ -206,11 +252,7 @@ CGDebugInfo::getClassName(const RecordDecl *RD) {    }    // Copy this name on the side and use its reference. -  size_t Length = Name.size() + TemplateArgList.size(); -  char *StrPtr = DebugInfoNames.Allocate<char>(Length); -  memcpy(StrPtr, Name.data(), Name.size()); -  memcpy(StrPtr + Name.size(), TemplateArgList.data(), TemplateArgList.size()); -  return StringRef(StrPtr, Length); +  return internString(Name, TemplateArgList);  }  /// getOrCreateFile - Get the file debug info descriptor for the input location. @@ -280,9 +322,7 @@ StringRef CGDebugInfo::getCurrentDirname() {      return CWDName;    SmallString<256> CWD;    llvm::sys::fs::current_path(CWD); -  char *CompDirnamePtr = DebugInfoNames.Allocate<char>(CWD.size()); -  memcpy(CompDirnamePtr, CWD.data(), CWD.size()); -  return CWDName = StringRef(CompDirnamePtr, CWD.size()); +  return CWDName = internString(CWD);  }  /// CreateCompileUnit - Create new compile unit. @@ -301,21 +341,20 @@ void CGDebugInfo::CreateCompileUnit() {    std::string MainFileDir;    if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {      MainFileDir = MainFile->getDir()->getName(); -    if (MainFileDir != ".") -      MainFileName = MainFileDir + "/" + MainFileName; +    if (MainFileDir != ".") { +      llvm::SmallString<1024> MainFileDirSS(MainFileDir);
 +      llvm::sys::path::append(MainFileDirSS, MainFileName);
 +      MainFileName = MainFileDirSS.str();
 +    }    }    // Save filename string. -  char *FilenamePtr = DebugInfoNames.Allocate<char>(MainFileName.length()); -  memcpy(FilenamePtr, MainFileName.c_str(), MainFileName.length()); -  StringRef Filename(FilenamePtr, MainFileName.length()); +  StringRef Filename = internString(MainFileName);    // Save split dwarf file string.    std::string SplitDwarfFile = CGM.getCodeGenOpts().SplitDwarfFile; -  char *SplitDwarfPtr = DebugInfoNames.Allocate<char>(SplitDwarfFile.length()); -  memcpy(SplitDwarfPtr, SplitDwarfFile.c_str(), SplitDwarfFile.length()); -  StringRef SplitDwarfFilename(SplitDwarfPtr, SplitDwarfFile.length()); -   +  StringRef SplitDwarfFilename = internString(SplitDwarfFile); +    unsigned LangTag;    const LangOptions &LO = CGM.getLangOpts();    if (LO.CPlusPlus) { @@ -339,12 +378,11 @@ void CGDebugInfo::CreateCompileUnit() {      RuntimeVers = LO.ObjCRuntime.isNonFragile() ? 2 : 1;    // Create new compile unit. -  DBuilder.createCompileUnit(LangTag, Filename, getCurrentDirname(), -                             Producer, LO.Optimize, -                             CGM.getCodeGenOpts().DwarfDebugFlags, -                             RuntimeVers, SplitDwarfFilename);    // FIXME - Eliminate TheCU. -  TheCU = llvm::DICompileUnit(DBuilder.getCU()); +  TheCU = DBuilder.createCompileUnit(LangTag, Filename, getCurrentDirname(), +                                     Producer, LO.Optimize, +                                     CGM.getCodeGenOpts().DwarfDebugFlags, +                                     RuntimeVers, SplitDwarfFilename);  }  /// CreateType - Get the Basic type from the cache or create a new @@ -360,12 +398,11 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) {    case BuiltinType::Dependent:      llvm_unreachable("Unexpected builtin type");    case BuiltinType::NullPtr: -    return DBuilder. -      createNullPtrType(BT->getName(CGM.getLangOpts())); +    return DBuilder.createNullPtrType();    case BuiltinType::Void:      return llvm::DIType();    case BuiltinType::ObjCClass: -    if (ClassTy.Verify()) +    if (ClassTy)        return ClassTy;      ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,                                           "objc_class", TheCU, @@ -377,16 +414,16 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) {      //  Class isa;      // } *id; -    if (ObjTy.Verify()) +    if (ObjTy)        return ObjTy; -    if (!ClassTy.Verify()) +    if (!ClassTy)        ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,                                             "objc_class", TheCU,                                             getOrCreateMainFile(), 0);      unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy); -     +      llvm::DIType ISATy = DBuilder.createPointerType(ClassTy, Size);      ObjTy = @@ -398,7 +435,7 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) {      return ObjTy;    }    case BuiltinType::ObjCSel: { -    if (SelTy.Verify()) +    if (SelTy)        return SelTy;      SelTy =        DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, @@ -411,7 +448,7 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) {      return getOrCreateStructPtrType("opencl_image1d_t",                                      OCLImage1dDITy);    case BuiltinType::OCLImage1dArray: -    return getOrCreateStructPtrType("opencl_image1d_array_t",  +    return getOrCreateStructPtrType("opencl_image1d_array_t",                                      OCLImage1dArrayDITy);    case BuiltinType::OCLImage1dBuffer:      return getOrCreateStructPtrType("opencl_image1d_buffer_t", @@ -471,7 +508,7 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) {    // Bit size, align and offset of the type.    uint64_t Size = CGM.getContext().getTypeSize(BT);    uint64_t Align = CGM.getContext().getTypeAlign(BT); -  llvm::DIType DbgTy =  +  llvm::DIType DbgTy =      DBuilder.createBasicType(BTName, Size, Align, Encoding);    return DbgTy;  } @@ -484,7 +521,7 @@ llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty) {    uint64_t Size = CGM.getContext().getTypeSize(Ty);    uint64_t Align = CGM.getContext().getTypeAlign(Ty); -  llvm::DIType DbgTy =  +  llvm::DIType DbgTy =      DBuilder.createBasicType("complex", Size, Align, Encoding);    return DbgTy; @@ -523,7 +560,7 @@ llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit) {    // No need to fill in the Name, Line, Size, Alignment, Offset in case of    // CVR derived types.    llvm::DIType DbgTy = DBuilder.createQualifiedType(Tag, FromTy); -   +    return DbgTy;  } @@ -537,20 +574,48 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty,        return getOrCreateType(CGM.getContext().getObjCIdType(), Unit);    llvm::DIType DbgTy = -    CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,  +    CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,                            Ty->getPointeeType(), Unit);    return DbgTy;  }  llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty,                                       llvm::DIFile Unit) { -  return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,  +  return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,                                 Ty->getPointeeType(), Unit);  } +/// In C++ mode, types have linkage, so we can rely on the ODR and +/// on their mangled names, if they're external. +static SmallString<256> +getUniqueTagTypeName(const TagType *Ty, CodeGenModule &CGM, +                     llvm::DICompileUnit TheCU) { +  SmallString<256> FullName; +  // FIXME: ODR should apply to ObjC++ exactly the same wasy it does to C++. +  // For now, only apply ODR with C++. +  const TagDecl *TD = Ty->getDecl(); +  if (TheCU.getLanguage() != llvm::dwarf::DW_LANG_C_plus_plus || +      !TD->isExternallyVisible()) +    return FullName; +  // Microsoft Mangler does not have support for mangleCXXRTTIName yet. +  if (CGM.getTarget().getCXXABI().isMicrosoft()) +    return FullName; + +  // TODO: This is using the RTTI name. Is there a better way to get +  // a unique string for a type? +  llvm::raw_svector_ostream Out(FullName); +  CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(QualType(Ty, 0), Out); +  Out.flush(); +  return FullName; +} +  // Creates a forward declaration for a RecordDecl in the given context. -llvm::DIType CGDebugInfo::createRecordFwdDecl(const RecordDecl *RD, -                                              llvm::DIDescriptor Ctx) { +llvm::DICompositeType +CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty, +                                      llvm::DIDescriptor Ctx) { +  const RecordDecl *RD = Ty->getDecl(); +  if (llvm::DIType T = getTypeOrNull(CGM.getContext().getRecordType(RD))) +    return llvm::DICompositeType(T);    llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());    unsigned Line = getLineNumber(RD->getLocation());    StringRef RDName = getClassName(RD); @@ -566,74 +631,18 @@ llvm::DIType CGDebugInfo::createRecordFwdDecl(const RecordDecl *RD,    }    // Create the type. -  return DBuilder.createForwardDecl(Tag, RDName, Ctx, DefUnit, Line); -} - -// Walk up the context chain and create forward decls for record decls, -// and normal descriptors for namespaces. -llvm::DIDescriptor CGDebugInfo::createContextChain(const Decl *Context) { -  if (!Context) -    return TheCU; - -  // See if we already have the parent. -  llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator -    I = RegionMap.find(Context); -  if (I != RegionMap.end()) { -    llvm::Value *V = I->second; -    return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(V)); -  } -   -  // Check namespace. -  if (const NamespaceDecl *NSDecl = dyn_cast<NamespaceDecl>(Context)) -    return llvm::DIDescriptor(getOrCreateNameSpace(NSDecl)); - -  if (const RecordDecl *RD = dyn_cast<RecordDecl>(Context)) { -    if (!RD->isDependentType()) { -      llvm::DIType Ty = getOrCreateLimitedType(CGM.getContext().getTypeDeclType(RD), -                                               getOrCreateMainFile()); -      return llvm::DIDescriptor(Ty); -    } -  } -  return TheCU; -} - -/// CreatePointeeType - Create Pointee type. If Pointee is a record -/// then emit record's fwd if debug info size reduction is enabled. -llvm::DIType CGDebugInfo::CreatePointeeType(QualType PointeeTy, -                                            llvm::DIFile Unit) { -  if (CGM.getCodeGenOpts().getDebugInfo() != CodeGenOptions::LimitedDebugInfo) -    return getOrCreateType(PointeeTy, Unit); - -  // Limit debug info for the pointee type. - -  // If we have an existing type, use that, it's still smaller than creating -  // a new type. -  llvm::DIType Ty = getTypeOrNull(PointeeTy); -  if (Ty.Verify()) return Ty; - -  // Handle qualifiers. -  if (PointeeTy.hasLocalQualifiers()) -    return CreateQualifiedType(PointeeTy, Unit); - -  if (const RecordType *RTy = dyn_cast<RecordType>(PointeeTy)) { -    RecordDecl *RD = RTy->getDecl(); -    llvm::DIDescriptor FDContext = -      getContextDescriptor(cast<Decl>(RD->getDeclContext())); -    llvm::DIType RetTy = createRecordFwdDecl(RD, FDContext); -    TypeCache[QualType(RTy, 0).getAsOpaquePtr()] = RetTy; -    return RetTy; -  } -  return getOrCreateType(PointeeTy, Unit); +  SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU); +  return DBuilder.createForwardDecl(Tag, RDName, Ctx, DefUnit, Line, 0, 0, 0, +                                    FullName);  }  llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag, -                                                const Type *Ty,  +                                                const Type *Ty,                                                  QualType PointeeTy,                                                  llvm::DIFile Unit) {    if (Tag == llvm::dwarf::DW_TAG_reference_type ||        Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) -    return DBuilder.createReferenceType(Tag, -                                        CreatePointeeType(PointeeTy, Unit)); +    return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit));    // Bit size, align and offset of the type.    // Size is always the size of a pointer. We can't use getTypeSize here @@ -642,25 +651,24 @@ llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,    uint64_t Size = CGM.getTarget().getPointerWidth(AS);    uint64_t Align = CGM.getContext().getTypeAlign(Ty); -  return DBuilder.createPointerType(CreatePointeeType(PointeeTy, Unit), -                                    Size, Align); +  return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size, +                                    Align);  } -llvm::DIType CGDebugInfo::getOrCreateStructPtrType(StringRef Name, llvm::DIType &Cache) { -    if (Cache.Verify()) -      return Cache; -    Cache = -      DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, -                                 Name, TheCU, getOrCreateMainFile(), -                                 0); -    unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy); -    Cache = DBuilder.createPointerType(Cache, Size); +llvm::DIType CGDebugInfo::getOrCreateStructPtrType(StringRef Name, +                                                   llvm::DIType &Cache) { +  if (Cache)      return Cache; +  Cache = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, Name, +                                     TheCU, getOrCreateMainFile(), 0); +  unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy); +  Cache = DBuilder.createPointerType(Cache, Size); +  return Cache;  }  llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,                                       llvm::DIFile Unit) { -  if (BlockLiteralGenericSet) +  if (BlockLiteralGeneric)      return BlockLiteralGeneric;    SmallVector<llvm::Value *, 8> EltTys; @@ -716,7 +724,6 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,                                      Unit, LineNo, FieldOffset, 0,                                      Flags, llvm::DIType(), Elements); -  BlockLiteralGenericSet = true;    BlockLiteralGeneric = DBuilder.createPointerType(EltTy, Size);    return BlockLiteralGeneric;  } @@ -725,16 +732,16 @@ llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit) {    // Typedefs are derived from some other type.  If we have a typedef of a    // typedef, make sure to emit the whole chain.    llvm::DIType Src = getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit); -  if (!Src.Verify()) +  if (!Src)      return llvm::DIType();    // We don't set size information, but do specify where the typedef was    // declared.    unsigned Line = getLineNumber(Ty->getDecl()->getLocation());    const TypedefNameDecl *TyDecl = Ty->getDecl(); -   +    llvm::DIDescriptor TypedefContext =      getContextDescriptor(cast<Decl>(Ty->getDecl()->getDeclContext())); -   +    return      DBuilder.createTypedef(Src, TyDecl->getName(), Unit, Line, TypedefContext);  } @@ -767,7 +774,7 @@ llvm::DIType CGDebugInfo::createFieldType(StringRef name,                                            AccessSpecifier AS,                                            uint64_t offsetInBits,                                            llvm::DIFile tunit, -                                          llvm::DIDescriptor scope) { +                                          llvm::DIScope scope) {    llvm::DIType debugType = getOrCreateType(type, tunit);    // Get the location for the field. @@ -839,20 +846,15 @@ CollectRecordLambdaFields(const CXXRecordDecl *CXXDecl,    }  } -/// CollectRecordStaticField - Helper for CollectRecordFields. -void CGDebugInfo:: -CollectRecordStaticField(const VarDecl *Var, -                         SmallVectorImpl<llvm::Value *> &elements, -                         llvm::DIType RecordTy) { +/// Helper for CollectRecordFields. +llvm::DIDerivedType +CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, +                                     llvm::DIType RecordTy) {    // Create the descriptor for the static variable, with or without    // constant initializers.    llvm::DIFile VUnit = getOrCreateFile(Var->getLocation());    llvm::DIType VTy = getOrCreateType(Var->getType(), VUnit); -  // Do not describe enums as static members. -  if (VTy.getTag() == llvm::dwarf::DW_TAG_enumeration_type) -    return; -    unsigned LineNumber = getLineNumber(Var->getLocation());    StringRef VName = Var->getName();    llvm::Constant *C = NULL; @@ -873,10 +875,10 @@ CollectRecordStaticField(const VarDecl *Var,    else if (Access == clang::AS_protected)      Flags |= llvm::DIDescriptor::FlagProtected; -  llvm::DIType GV = DBuilder.createStaticMemberType(RecordTy, VName, VUnit, -                                                    LineNumber, VTy, Flags, C); -  elements.push_back(GV); +  llvm::DIDerivedType GV = DBuilder.createStaticMemberType( +      RecordTy, VName, VUnit, LineNumber, VTy, Flags, C);    StaticDataMemberCache[Var->getCanonicalDecl()] = llvm::WeakVH(GV); +  return GV;  }  /// CollectRecordNormalField - Helper for CollectRecordFields. @@ -908,10 +910,10 @@ CollectRecordNormalField(const FieldDecl *field, uint64_t OffsetInBits,  /// CollectRecordFields - A helper function to collect debug info for  /// record fields. This is used while creating debug info entry for a Record. -void CGDebugInfo:: -CollectRecordFields(const RecordDecl *record, llvm::DIFile tunit, -                    SmallVectorImpl<llvm::Value *> &elements, -                    llvm::DIType RecordTy) { +void CGDebugInfo::CollectRecordFields(const RecordDecl *record, +                                      llvm::DIFile tunit, +                                      SmallVectorImpl<llvm::Value *> &elements, +                                      llvm::DICompositeType RecordTy) {    const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(record);    if (CXXDecl && CXXDecl->isLambda()) @@ -922,24 +924,22 @@ CollectRecordFields(const RecordDecl *record, llvm::DIFile tunit,      // Field number for non-static fields.      unsigned fieldNo = 0; -    // Bookkeeping for an ms struct, which ignores certain fields. -    bool IsMsStruct = record->isMsStruct(CGM.getContext()); -    const FieldDecl *LastFD = 0; -      // Static and non-static members should appear in the same order as      // the corresponding declarations in the source program.      for (RecordDecl::decl_iterator I = record->decls_begin(),             E = record->decls_end(); I != E; ++I) -      if (const VarDecl *V = dyn_cast<VarDecl>(*I)) -        CollectRecordStaticField(V, elements, RecordTy); -      else if (FieldDecl *field = dyn_cast<FieldDecl>(*I)) { -        if (IsMsStruct) { -          // Zero-length bitfields following non-bitfield members are -          // completely ignored; we don't even count them. -          if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((field), LastFD)) -            continue; -          LastFD = field; -        } +      if (const VarDecl *V = dyn_cast<VarDecl>(*I)) { +        // Reuse the existing static member declaration if one exists +        llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator MI = +            StaticDataMemberCache.find(V->getCanonicalDecl()); +        if (MI != StaticDataMemberCache.end()) { +          assert(MI->second && +                 "Static data member declaration should still exist"); +          elements.push_back( +              llvm::DIDerivedType(cast<llvm::MDNode>(MI->second))); +        } else +          elements.push_back(CreateRecordStaticField(V, RecordTy)); +      } else if (FieldDecl *field = dyn_cast<FieldDecl>(*I)) {          CollectRecordNormalField(field, layout.getFieldOffset(fieldNo),                                   tunit, elements, RecordTy); @@ -952,17 +952,17 @@ CollectRecordFields(const RecordDecl *record, llvm::DIFile tunit,  /// getOrCreateMethodType - CXXMethodDecl's type is a FunctionType. This  /// function type is not updated to include implicit "this" pointer. Use this  /// routine to get a method type which includes "this" pointer. -llvm::DIType +llvm::DICompositeType  CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,                                     llvm::DIFile Unit) {    const FunctionProtoType *Func = Method->getType()->getAs<FunctionProtoType>();    if (Method->isStatic()) -    return getOrCreateType(QualType(Func, 0), Unit); +    return llvm::DICompositeType(getOrCreateType(QualType(Func, 0), Unit));    return getOrCreateInstanceMethodType(Method->getThisType(CGM.getContext()),                                         Func, Unit);  } -llvm::DIType CGDebugInfo::getOrCreateInstanceMethodType( +llvm::DICompositeType CGDebugInfo::getOrCreateInstanceMethodType(      QualType ThisPtr, const FunctionProtoType *Func, llvm::DIFile Unit) {    // Add "this" pointer.    llvm::DIArray Args = llvm::DICompositeType( @@ -984,7 +984,8 @@ llvm::DIType CGDebugInfo::getOrCreateInstanceMethodType(      uint64_t Size = CGM.getTarget().getPointerWidth(AS);      uint64_t Align = CGM.getContext().getTypeAlign(ThisPtrTy);      llvm::DIType PointeeType = getOrCreateType(PointeeTy, Unit); -    llvm::DIType ThisPtrType = DBuilder.createPointerType(PointeeType, Size, Align); +    llvm::DIType ThisPtrType = +      DBuilder.createPointerType(PointeeType, Size, Align);      TypeCache[ThisPtr.getAsOpaquePtr()] = ThisPtrType;      // TODO: This and the artificial type below are misleading, the      // types aren't artificial the argument is, but the current @@ -1007,7 +1008,7 @@ llvm::DIType CGDebugInfo::getOrCreateInstanceMethodType(    return DBuilder.createSubroutineType(Unit, EltTypeArray);  } -/// isFunctionLocalClass - Return true if CXXRecordDecl is defined  +/// isFunctionLocalClass - Return true if CXXRecordDecl is defined  /// inside a function.  static bool isFunctionLocalClass(const CXXRecordDecl *RD) {    if (const CXXRecordDecl *NRD = dyn_cast<CXXRecordDecl>(RD->getDeclContext())) @@ -1023,11 +1024,11 @@ llvm::DISubprogram  CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,                                       llvm::DIFile Unit,                                       llvm::DIType RecordTy) { -  bool IsCtorOrDtor =  +  bool IsCtorOrDtor =      isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method); -   +    StringRef MethodName = getFunctionName(Method); -  llvm::DIType MethodTy = getOrCreateMethodType(Method, Unit); +  llvm::DICompositeType MethodTy = getOrCreateMethodType(Method, Unit);    // Since a single ctor/dtor corresponds to multiple functions, it doesn't    // make sense to give a single ctor/dtor a linkage name. @@ -1036,24 +1037,32 @@ CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,      MethodLinkageName = CGM.getMangledName(Method);    // Get the location for the method. -  llvm::DIFile MethodDefUnit = getOrCreateFile(Method->getLocation()); -  unsigned MethodLine = getLineNumber(Method->getLocation()); +  llvm::DIFile MethodDefUnit; +  unsigned MethodLine = 0; +  if (!Method->isImplicit()) { +    MethodDefUnit = getOrCreateFile(Method->getLocation()); +    MethodLine = getLineNumber(Method->getLocation()); +  }    // Collect virtual method info.    llvm::DIType ContainingType; -  unsigned Virtuality = 0;  +  unsigned Virtuality = 0;    unsigned VIndex = 0; -   +    if (Method->isVirtual()) {      if (Method->isPure())        Virtuality = llvm::dwarf::DW_VIRTUALITY_pure_virtual;      else        Virtuality = llvm::dwarf::DW_VIRTUALITY_virtual; -     +      // It doesn't make sense to give a virtual destructor a vtable index,      // since a single destructor has two entries in the vtable. -    if (!isa<CXXDestructorDecl>(Method)) -      VIndex = CGM.getVTableContext().getMethodVTableIndex(Method); +    // FIXME: Add proper support for debug info for virtual calls in +    // the Microsoft ABI, where we may use multiple vptrs to make a vftable +    // lookup if we have multiple or virtual inheritance. +    if (!isa<CXXDestructorDecl>(Method) && +        !CGM.getTarget().getCXXABI().isMicrosoft()) +      VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(Method);      ContainingType = RecordTy;    } @@ -1068,7 +1077,7 @@ CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,    if (const CXXConstructorDecl *CXXC = dyn_cast<CXXConstructorDecl>(Method)) {      if (CXXC->isExplicit())        Flags |= llvm::DIDescriptor::FlagExplicit; -  } else if (const CXXConversionDecl *CXXC =  +  } else if (const CXXConversionDecl *CXXC =               dyn_cast<CXXConversionDecl>(Method)) {      if (CXXC->isExplicit())        Flags |= llvm::DIDescriptor::FlagExplicit; @@ -1078,21 +1087,21 @@ CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,    llvm::DIArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);    llvm::DISubprogram SP = -    DBuilder.createMethod(RecordTy, MethodName, MethodLinkageName,  +    DBuilder.createMethod(RecordTy, MethodName, MethodLinkageName,                            MethodDefUnit, MethodLine, -                          MethodTy, /*isLocalToUnit=*/false,  +                          MethodTy, /*isLocalToUnit=*/false,                            /* isDefinition=*/ false,                            Virtuality, VIndex, ContainingType,                            Flags, CGM.getLangOpts().Optimize, NULL,                            TParamsArray); -   +    SPCache[Method->getCanonicalDecl()] = llvm::WeakVH(SP);    return SP;  }  /// CollectCXXMemberFunctions - A helper function to collect debug info for -/// C++ member functions. This is used while creating debug info entry for  +/// C++ member functions. This is used while creating debug info entry for  /// a Record.  void CGDebugInfo::  CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit, @@ -1104,40 +1113,42 @@ CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit,    // the functions.    for(DeclContext::decl_iterator I = RD->decls_begin(),          E = RD->decls_end(); I != E; ++I) { -    Decl *D = *I; -    if (D->isImplicit() && !D->isUsed()) -      continue; - -    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) -      EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy)); -    else if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D)) +    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*I)) { +      // Reuse the existing member function declaration if it exists. +      // It may be associated with the declaration of the type & should be +      // reused as we're building the definition. +      // +      // This situation can arise in the vtable-based debug info reduction where +      // implicit members are emitted in a non-vtable TU. +      llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator MI = +          SPCache.find(Method->getCanonicalDecl()); +      if (MI == SPCache.end()) { +        // If the member is implicit, lazily create it when we see the +        // definition, not before. (an ODR-used implicit default ctor that's +        // never actually code generated should not produce debug info) +        if (!Method->isImplicit()) +          EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy)); +      } else +        EltTys.push_back(MI->second); +    } else if (const FunctionTemplateDecl *FTD = +                   dyn_cast<FunctionTemplateDecl>(*I)) { +      // Add any template specializations that have already been seen. Like +      // implicit member functions, these may have been added to a declaration +      // in the case of vtable-based debug info reduction.        for (FunctionTemplateDecl::spec_iterator SI = FTD->spec_begin(), -             SE = FTD->spec_end(); SI != SE; ++SI) -        EltTys.push_back(CreateCXXMemberFunction(cast<CXXMethodDecl>(*SI), Unit, -                                                 RecordTy)); -  } -}                                  - -/// CollectCXXFriends - A helper function to collect debug info for -/// C++ base classes. This is used while creating debug info entry for -/// a Record. -void CGDebugInfo:: -CollectCXXFriends(const CXXRecordDecl *RD, llvm::DIFile Unit, -                SmallVectorImpl<llvm::Value *> &EltTys, -                llvm::DIType RecordTy) { -  for (CXXRecordDecl::friend_iterator BI = RD->friend_begin(), -         BE = RD->friend_end(); BI != BE; ++BI) { -    if ((*BI)->isUnsupportedFriend()) -      continue; -    if (TypeSourceInfo *TInfo = (*BI)->getFriendType()) -      EltTys.push_back(DBuilder.createFriend(RecordTy,  -                                             getOrCreateType(TInfo->getType(),  -                                                             Unit))); +                                               SE = FTD->spec_end(); +           SI != SE; ++SI) { +        llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator MI = +            SPCache.find(cast<CXXMethodDecl>(*SI)->getCanonicalDecl()); +        if (MI != SPCache.end()) +          EltTys.push_back(MI->second); +      } +    }    }  }  /// CollectCXXBases - A helper function to collect debug info for -/// C++ base classes. This is used while creating debug info entry for  +/// C++ base classes. This is used while creating debug info entry for  /// a Record.  void CGDebugInfo::  CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile Unit, @@ -1149,30 +1160,30 @@ CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile Unit,           BE = RD->bases_end(); BI != BE; ++BI) {      unsigned BFlags = 0;      uint64_t BaseOffset; -     +      const CXXRecordDecl *Base =        cast<CXXRecordDecl>(BI->getType()->getAs<RecordType>()->getDecl()); -     +      if (BI->isVirtual()) {        // virtual base offset offset is -ve. The code generator emits dwarf        // expression where it expects +ve number. -      BaseOffset =  -        0 - CGM.getVTableContext() +      BaseOffset = +        0 - CGM.getItaniumVTableContext()                 .getVirtualBaseOffsetOffset(RD, Base).getQuantity();        BFlags = llvm::DIDescriptor::FlagVirtual;      } else        BaseOffset = CGM.getContext().toBits(RL.getBaseClassOffset(Base));      // FIXME: Inconsistent units for BaseOffset. It is in bytes when      // BI->isVirtual() and bits when not. -     +      AccessSpecifier Access = BI->getAccessSpecifier();      if (Access == clang::AS_private)        BFlags |= llvm::DIDescriptor::FlagPrivate;      else if (Access == clang::AS_protected)        BFlags |= llvm::DIDescriptor::FlagProtected; -     -    llvm::DIType DTy =  -      DBuilder.createInheritance(RecordTy,                                      + +    llvm::DIType DTy = +      DBuilder.createInheritance(RecordTy,                                   getOrCreateType(BI->getType(), Unit),                                   BaseOffset, BFlags);      EltTys.push_back(DTy); @@ -1182,23 +1193,119 @@ CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile Unit,  /// CollectTemplateParams - A helper function to collect template parameters.  llvm::DIArray CGDebugInfo::  CollectTemplateParams(const TemplateParameterList *TPList, -                      const TemplateArgumentList &TAList, +                      ArrayRef<TemplateArgument> TAList,                        llvm::DIFile Unit) { -  SmallVector<llvm::Value *, 16> TemplateParams;   +  SmallVector<llvm::Value *, 16> TemplateParams;    for (unsigned i = 0, e = TAList.size(); i != e; ++i) {      const TemplateArgument &TA = TAList[i]; -    const NamedDecl *ND = TPList->getParam(i); -    if (TA.getKind() == TemplateArgument::Type) { +    StringRef Name; +    if (TPList) +      Name = TPList->getParam(i)->getName(); +    switch (TA.getKind()) { +    case TemplateArgument::Type: {        llvm::DIType TTy = getOrCreateType(TA.getAsType(), Unit);        llvm::DITemplateTypeParameter TTP = -        DBuilder.createTemplateTypeParameter(TheCU, ND->getName(), TTy); +          DBuilder.createTemplateTypeParameter(TheCU, Name, TTy);        TemplateParams.push_back(TTP); -    } else if (TA.getKind() == TemplateArgument::Integral) { +    } break; +    case TemplateArgument::Integral: {        llvm::DIType TTy = getOrCreateType(TA.getIntegralType(), Unit);        llvm::DITemplateValueParameter TVP = -        DBuilder.createTemplateValueParameter(TheCU, ND->getName(), TTy, -                                             TA.getAsIntegral().getZExtValue()); -      TemplateParams.push_back(TVP);           +          DBuilder.createTemplateValueParameter( +              TheCU, Name, TTy, +              llvm::ConstantInt::get(CGM.getLLVMContext(), TA.getAsIntegral())); +      TemplateParams.push_back(TVP); +    } break; +    case TemplateArgument::Declaration: { +      const ValueDecl *D = TA.getAsDecl(); +      bool InstanceMember = D->isCXXInstanceMember(); +      QualType T = InstanceMember +                       ? CGM.getContext().getMemberPointerType( +                             D->getType(), cast<RecordDecl>(D->getDeclContext()) +                                               ->getTypeForDecl()) +                       : CGM.getContext().getPointerType(D->getType()); +      llvm::DIType TTy = getOrCreateType(T, Unit); +      llvm::Value *V = 0; +      // Variable pointer template parameters have a value that is the address +      // of the variable. +      if (const VarDecl *VD = dyn_cast<VarDecl>(D)) +        V = CGM.GetAddrOfGlobalVar(VD); +      // Member function pointers have special support for building them, though +      // this is currently unsupported in LLVM CodeGen. +      if (InstanceMember) { +        if (const CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(D)) +          V = CGM.getCXXABI().EmitMemberPointer(method); +      } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) +        V = CGM.GetAddrOfFunction(FD); +      // Member data pointers have special handling too to compute the fixed +      // offset within the object. +      if (isa<FieldDecl>(D)) { +        // These five lines (& possibly the above member function pointer +        // handling) might be able to be refactored to use similar code in +        // CodeGenModule::getMemberPointerConstant +        uint64_t fieldOffset = CGM.getContext().getFieldOffset(D); +        CharUnits chars = +            CGM.getContext().toCharUnitsFromBits((int64_t) fieldOffset); +        V = CGM.getCXXABI().EmitMemberDataPointer( +            cast<MemberPointerType>(T.getTypePtr()), chars); +      } +      llvm::DITemplateValueParameter TVP = +          DBuilder.createTemplateValueParameter(TheCU, Name, TTy, +                                                V->stripPointerCasts()); +      TemplateParams.push_back(TVP); +    } break; +    case TemplateArgument::NullPtr: { +      QualType T = TA.getNullPtrType(); +      llvm::DIType TTy = getOrCreateType(T, Unit); +      llvm::Value *V = 0; +      // Special case member data pointer null values since they're actually -1 +      // instead of zero. +      if (const MemberPointerType *MPT = +              dyn_cast<MemberPointerType>(T.getTypePtr())) +        // But treat member function pointers as simple zero integers because +        // it's easier than having a special case in LLVM's CodeGen. If LLVM +        // CodeGen grows handling for values of non-null member function +        // pointers then perhaps we could remove this special case and rely on +        // EmitNullMemberPointer for member function pointers. +        if (MPT->isMemberDataPointer()) +          V = CGM.getCXXABI().EmitNullMemberPointer(MPT); +      if (!V) +        V = llvm::ConstantInt::get(CGM.Int8Ty, 0); +      llvm::DITemplateValueParameter TVP = +          DBuilder.createTemplateValueParameter(TheCU, Name, TTy, V); +      TemplateParams.push_back(TVP); +    } break; +    case TemplateArgument::Template: { +      llvm::DITemplateValueParameter TVP = +          DBuilder.createTemplateTemplateParameter( +              TheCU, Name, llvm::DIType(), +              TA.getAsTemplate().getAsTemplateDecl() +                  ->getQualifiedNameAsString()); +      TemplateParams.push_back(TVP); +    } break; +    case TemplateArgument::Pack: { +      llvm::DITemplateValueParameter TVP = +          DBuilder.createTemplateParameterPack( +              TheCU, Name, llvm::DIType(), +              CollectTemplateParams(NULL, TA.getPackAsArray(), Unit)); +      TemplateParams.push_back(TVP); +    } break; +    case TemplateArgument::Expression: { +      const Expr *E = TA.getAsExpr(); +      QualType T = E->getType(); +      llvm::Value *V = CGM.EmitConstantExpr(E, T); +      assert(V && "Expression in template argument isn't constant"); +      llvm::DIType TTy = getOrCreateType(T, Unit); +      llvm::DITemplateValueParameter TVP = +          DBuilder.createTemplateValueParameter(TheCU, Name, TTy, +                                                V->stripPointerCasts()); +      TemplateParams.push_back(TVP); +    } break; +    // And the following should never occur: +    case TemplateArgument::TemplateExpansion: +    case TemplateArgument::Null: +      llvm_unreachable( +          "These argument types shouldn't exist in concrete types");      }    }    return DBuilder.getOrCreateArray(TemplateParams); @@ -1213,8 +1320,8 @@ CollectFunctionTemplateParams(const FunctionDecl *FD, llvm::DIFile Unit) {      const TemplateParameterList *TList =        FD->getTemplateSpecializationInfo()->getTemplate()        ->getTemplateParameters(); -    return  -      CollectTemplateParams(TList, *FD->getTemplateSpecializationArgs(), Unit); +    return CollectTemplateParams( +        TList, FD->getTemplateSpecializationArgs()->asArray(), Unit);    }    return llvm::DIArray();  } @@ -1227,12 +1334,12 @@ CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TSpecial,    llvm::PointerUnion<ClassTemplateDecl *,                       ClassTemplatePartialSpecializationDecl *>      PU = TSpecial->getSpecializedTemplateOrPartial(); -   +    TemplateParameterList *TPList = PU.is<ClassTemplateDecl *>() ?      PU.get<ClassTemplateDecl *>()->getTemplateParameters() :      PU.get<ClassTemplatePartialSpecializationDecl *>()->getTemplateParameters();    const TemplateArgumentList &TAList = TSpecial->getTemplateInstantiationArgs(); -  return CollectTemplateParams(TPList, TAList, Unit); +  return CollectTemplateParams(TPList, TAList.asArray(), Unit);  }  /// getOrCreateVTablePtrType - Return debug info descriptor for vtable. @@ -1255,13 +1362,8 @@ llvm::DIType CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile Unit) {  /// getVTableName - Get vtable name for the given Class.  StringRef CGDebugInfo::getVTableName(const CXXRecordDecl *RD) { -  // Construct gdb compatible name name. -  std::string Name = "_vptr$" + RD->getNameAsString(); - -  // Copy this name on the side and use its reference. -  char *StrPtr = DebugInfoNames.Allocate<char>(Name.length()); -  memcpy(StrPtr, Name.data(), Name.length()); -  return StringRef(StrPtr, Name.length()); +  // Copy the gdb compatible name on the side and use its reference. +  return internString("_vptr$", RD->getNameAsString());  } @@ -1283,15 +1385,16 @@ CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile Unit,    unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);    llvm::DIType VPTR      = DBuilder.createMemberType(Unit, getVTableName(RD), Unit, -                                0, Size, 0, 0, llvm::DIDescriptor::FlagArtificial, +                                0, Size, 0, 0, +                                llvm::DIDescriptor::FlagArtificial,                                  getOrCreateVTablePtrType(Unit));    EltTys.push_back(VPTR);  } -/// getOrCreateRecordType - Emit record type's standalone debug info.  -llvm::DIType CGDebugInfo::getOrCreateRecordType(QualType RTy,  +/// getOrCreateRecordType - Emit record type's standalone debug info. +llvm::DIType CGDebugInfo::getOrCreateRecordType(QualType RTy,                                                  SourceLocation Loc) { -  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo); +  assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);    llvm::DIType T = getOrCreateType(RTy, getOrCreateFile(Loc));    return T;  } @@ -1300,15 +1403,76 @@ llvm::DIType CGDebugInfo::getOrCreateRecordType(QualType RTy,  /// debug info.  llvm::DIType CGDebugInfo::getOrCreateInterfaceType(QualType D,                                                     SourceLocation Loc) { -  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo); +  assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);    llvm::DIType T = getOrCreateType(D, getOrCreateFile(Loc));    RetainedTypes.push_back(D.getAsOpaquePtr());    return T;  } +void CGDebugInfo::completeType(const RecordDecl *RD) { +  if (DebugKind > CodeGenOptions::LimitedDebugInfo || +      !CGM.getLangOpts().CPlusPlus) +    completeRequiredType(RD); +} + +void CGDebugInfo::completeRequiredType(const RecordDecl *RD) { +  if (const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) +    if (CXXDecl->isDynamicClass()) +      return; + +  QualType Ty = CGM.getContext().getRecordType(RD); +  llvm::DIType T = getTypeOrNull(Ty); +  if (T && T.isForwardDecl()) +    completeClassData(RD); +} + +void CGDebugInfo::completeClassData(const RecordDecl *RD) { +  if (DebugKind <= CodeGenOptions::DebugLineTablesOnly) +    return; +  QualType Ty = CGM.getContext().getRecordType(RD); +  void* TyPtr = Ty.getAsOpaquePtr(); +  if (CompletedTypeCache.count(TyPtr)) +    return; +  llvm::DIType Res = CreateTypeDefinition(Ty->castAs<RecordType>()); +  assert(!Res.isForwardDecl()); +  CompletedTypeCache[TyPtr] = Res; +  TypeCache[TyPtr] = Res; +} +  /// CreateType - get structure or union type.  llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) {    RecordDecl *RD = Ty->getDecl(); +  const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD); +  // Always emit declarations for types that aren't required to be complete when +  // in limit-debug-info mode. If the type is later found to be required to be +  // complete this declaration will be upgraded to a definition by +  // `completeRequiredType`. +  // If the type is dynamic, only emit the definition in TUs that require class +  // data. This is handled by `completeClassData`. +  llvm::DICompositeType T(getTypeOrNull(QualType(Ty, 0))); +  // If we've already emitted the type, just use that, even if it's only a +  // declaration. The completeType, completeRequiredType, and completeClassData +  // callbacks will handle promoting the declaration to a definition. +  if (T || +      (DebugKind <= CodeGenOptions::LimitedDebugInfo && +       // Under -flimit-debug-info, emit only a declaration unless the type is +       // required to be complete. +       !RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) || +      // If the class is dynamic, only emit a declaration. A definition will be +      // emitted whenever the vtable is emitted. +      (CXXDecl && CXXDecl->hasDefinition() && CXXDecl->isDynamicClass()) || T) { +    llvm::DIDescriptor FDContext = +      getContextDescriptor(cast<Decl>(RD->getDeclContext())); +    if (!T) +      T = getOrCreateRecordFwdDecl(Ty, FDContext); +    return T; +  } + +  return CreateTypeDefinition(Ty); +} + +llvm::DIType CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) { +  RecordDecl *RD = Ty->getDecl();    // Get overall information about the record type for the debug info.    llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation()); @@ -1320,14 +1484,16 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) {    // may refer to the forward decl if the struct is recursive) and replace all    // uses of the forward declaration with the final definition. -  llvm::DICompositeType FwdDecl( -      getOrCreateLimitedType(QualType(Ty, 0), DefUnit)); -  assert(FwdDecl.Verify() && -         "The debug type of a RecordType should be a DICompositeType"); +  llvm::DICompositeType FwdDecl(getOrCreateLimitedType(Ty, DefUnit)); +  assert(FwdDecl.isCompositeType() && +         "The debug type of a RecordType should be a llvm::DICompositeType");    if (FwdDecl.isForwardDecl())      return FwdDecl; +  if (const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) +    CollectContainingType(CXXDecl, FwdDecl); +    // Push the struct on region stack.    LexicalBlockStack.push_back(&*FwdDecl);    RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl); @@ -1337,6 +1503,7 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) {    // Convert all the elements.    SmallVector<llvm::Value *, 16> EltTys; +  // what about nested types?    // Note: The split of CXXDecl information here is intentional, the    // gdb tests will depend on a certain ordering at printout. The debug @@ -1350,20 +1517,14 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) {    // Collect data fields (including static variables and any initializers).    CollectRecordFields(RD, DefUnit, EltTys, FwdDecl); -  llvm::DIArray TParamsArray; -  if (CXXDecl) { +  if (CXXDecl)      CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl); -    CollectCXXFriends(CXXDecl, DefUnit, EltTys, FwdDecl); -    if (const ClassTemplateSpecializationDecl *TSpecial -        = dyn_cast<ClassTemplateSpecializationDecl>(RD)) -      TParamsArray = CollectCXXTemplateParams(TSpecial, DefUnit); -  }    LexicalBlockStack.pop_back();    RegionMap.erase(Ty->getDecl());    llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys); -  FwdDecl.setTypeArray(Elements, TParamsArray); +  FwdDecl.setTypeArray(Elements);    RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);    return FwdDecl; @@ -1376,6 +1537,31 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCObjectType *Ty,    return getOrCreateType(Ty->getBaseType(), Unit);  } + +/// \return true if Getter has the default name for the property PD. +static bool hasDefaultGetterName(const ObjCPropertyDecl *PD, +                                 const ObjCMethodDecl *Getter) { +  assert(PD); +  if (!Getter) +    return true; + +  assert(Getter->getDeclName().isObjCZeroArgSelector()); +  return PD->getName() == +    Getter->getDeclName().getObjCSelector().getNameForSlot(0); +} + +/// \return true if Setter has the default name for the property PD. +static bool hasDefaultSetterName(const ObjCPropertyDecl *PD, +                                 const ObjCMethodDecl *Setter) { +  assert(PD); +  if (!Setter) +    return true; + +  assert(Setter->getDeclName().isObjCOneArgSelector()); +  return SelectorTable::constructSetterName(PD->getName()) == +    Setter->getDeclName().getObjCSelector().getNameForSlot(0); +} +  /// CreateType - get objective-c interface type.  llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,                                       llvm::DIFile Unit) { @@ -1418,8 +1604,8 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,    // will find it and we're emitting the complete type.    QualType QualTy = QualType(Ty, 0);    CompletedTypeCache[QualTy.getAsOpaquePtr()] = RealDecl; -  // Push the struct on region stack. +  // Push the struct on region stack.    LexicalBlockStack.push_back(static_cast<llvm::MDNode*>(RealDecl));    RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl); @@ -1432,12 +1618,13 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,        getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);      if (!SClassTy.isValid())        return llvm::DIType(); -     +      llvm::DIType InhTag =        DBuilder.createInheritance(RealDecl, SClassTy, 0, 0);      EltTys.push_back(InhTag);    } +  // Create entries for all of the properties.    for (ObjCContainerDecl::prop_iterator I = ID->prop_begin(),           E = ID->prop_end(); I != E; ++I) {      const ObjCPropertyDecl *PD = *I; @@ -1449,9 +1636,9 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,      llvm::MDNode *PropertyNode =        DBuilder.createObjCProperty(PD->getName(),                                    PUnit, PLine, -                                  (Getter && Getter->isImplicit()) ? "" : +                                  hasDefaultGetterName(PD, Getter) ? "" :                                    getSelectorName(PD->getGetterName()), -                                  (Setter && Setter->isImplicit()) ? "" : +                                  hasDefaultSetterName(PD, Setter) ? "" :                                    getSelectorName(PD->getSetterName()),                                    PD->getPropertyAttributes(),                                    getOrCreateType(PD->getType(), PUnit)); @@ -1465,7 +1652,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,      llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);      if (!FieldTy.isValid())        return llvm::DIType(); -     +      StringRef FieldName = Field->getName();      // Ignore unnamed fields. @@ -1483,8 +1670,8 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,        // Bit size, align and offset of the type.        FieldSize = Field->isBitField() -        ? Field->getBitWidthValue(CGM.getContext()) -        : CGM.getContext().getTypeSize(FType); +                      ? Field->getBitWidthValue(CGM.getContext()) +                      : CGM.getContext().getTypeSize(FType);        FieldAlign = CGM.getContext().getTypeAlign(FType);      } @@ -1512,7 +1699,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,      llvm::MDNode *PropertyNode = NULL;      if (ObjCImplementationDecl *ImpD = ID->getImplementation()) { -      if (ObjCPropertyImplDecl *PImpD =  +      if (ObjCPropertyImplDecl *PImpD =            ImpD->FindPropertyImplIvarDecl(Field->getIdentifier())) {          if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {            SourceLocation Loc = PD->getLocation(); @@ -1523,9 +1710,9 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,            PropertyNode =              DBuilder.createObjCProperty(PD->getName(),                                          PUnit, PLine, -                                        (Getter && Getter->isImplicit()) ? "" : +                                        hasDefaultGetterName(PD, Getter) ? "" :                                          getSelectorName(PD->getGetterName()), -                                        (Setter && Setter->isImplicit()) ? "" : +                                        hasDefaultSetterName(PD, Setter) ? "" :                                          getSelectorName(PD->getSetterName()),                                          PD->getPropertyAttributes(),                                          getOrCreateType(PD->getType(), PUnit)); @@ -1547,7 +1734,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,    // private ivars that we would miss otherwise.    if (ID->getImplementation() == 0)      CompletedTypeCache.erase(QualTy.getAsOpaquePtr()); -   +    LexicalBlockStack.pop_back();    return RealDecl;  } @@ -1585,7 +1772,7 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,        Align = 0;      else        Align = CGM.getContext().getTypeAlign(Ty->getElementType()); -  } else if (Ty->isDependentSizedArrayType() || Ty->isIncompleteType()) { +  } else if (Ty->isIncompleteType()) {      Size = 0;      Align = 0;    } else { @@ -1610,7 +1797,7 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,      int64_t Count = -1;         // Count == -1 is an unbounded array.      if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty))        Count = CAT->getSize().getZExtValue(); -     +      // FIXME: Verify this is right for VLAs.      Subscripts.push_back(DBuilder.getOrCreateSubrange(0, Count));      EltTy = Ty->getElementType(); @@ -1618,30 +1805,30 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,    llvm::DIArray SubscriptArray = DBuilder.getOrCreateArray(Subscripts); -  llvm::DIType DbgTy =  +  llvm::DIType DbgTy =      DBuilder.createArrayType(Size, Align, getOrCreateType(EltTy, Unit),                               SubscriptArray);    return DbgTy;  } -llvm::DIType CGDebugInfo::CreateType(const LValueReferenceType *Ty,  +llvm::DIType CGDebugInfo::CreateType(const LValueReferenceType *Ty,                                       llvm::DIFile Unit) { -  return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type,  +  return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type,                                 Ty, Ty->getPointeeType(), Unit);  } -llvm::DIType CGDebugInfo::CreateType(const RValueReferenceType *Ty,  +llvm::DIType CGDebugInfo::CreateType(const RValueReferenceType *Ty,                                       llvm::DIFile Unit) { -  return CreatePointerLikeType(llvm::dwarf::DW_TAG_rvalue_reference_type,  +  return CreatePointerLikeType(llvm::dwarf::DW_TAG_rvalue_reference_type,                                 Ty, Ty->getPointeeType(), Unit);  } -llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty,  +llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty,                                       llvm::DIFile U) {    llvm::DIType ClassType = getOrCreateType(QualType(Ty->getClass(), 0), U);    if (!Ty->getPointeeType()->isFunctionType())      return DBuilder.createMemberPointerType( -        CreatePointeeType(Ty->getPointeeType(), U), ClassType); +        getOrCreateType(Ty->getPointeeType(), U), ClassType);    return DBuilder.createMemberPointerType(getOrCreateInstanceMethodType(        CGM.getContext().getPointerType(            QualType(Ty->getClass(), Ty->getPointeeType().getCVRQualifiers())), @@ -1649,7 +1836,7 @@ llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty,                                            ClassType);  } -llvm::DIType CGDebugInfo::CreateType(const AtomicType *Ty,  +llvm::DIType CGDebugInfo::CreateType(const AtomicType *Ty,                                       llvm::DIFile U) {    // Ignore the atomic wrapping    // FIXME: What is the correct representation? @@ -1657,7 +1844,8 @@ llvm::DIType CGDebugInfo::CreateType(const AtomicType *Ty,  }  /// CreateEnumType - get enumeration type. -llvm::DIType CGDebugInfo::CreateEnumType(const EnumDecl *ED) { +llvm::DIType CGDebugInfo::CreateEnumType(const EnumType *Ty) { +  const EnumDecl *ED = Ty->getDecl();    uint64_t Size = 0;    uint64_t Align = 0;    if (!ED->getTypeForDecl()->isIncompleteType()) { @@ -1665,6 +1853,8 @@ llvm::DIType CGDebugInfo::CreateEnumType(const EnumDecl *ED) {      Align = CGM.getContext().getTypeAlign(ED->getTypeForDecl());    } +  SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU); +    // If this is just a forward declaration, construct an appropriately    // marked node and just return it.    if (!ED->getDefinition()) { @@ -1675,7 +1865,7 @@ llvm::DIType CGDebugInfo::CreateEnumType(const EnumDecl *ED) {      StringRef EDName = ED->getName();      return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_enumeration_type,                                        EDName, EDContext, DefUnit, Line, 0, -                                      Size, Align); +                                      Size, Align, FullName);    }    // Create DIEnumerator elements for each enumerator. @@ -1686,7 +1876,7 @@ llvm::DIType CGDebugInfo::CreateEnumType(const EnumDecl *ED) {         Enum != EnumEnd; ++Enum) {      Enumerators.push_back(        DBuilder.createEnumerator(Enum->getName(), -                                Enum->getInitVal().getZExtValue())); +                                Enum->getInitVal().getSExtValue()));    }    // Return a CompositeType for the enum itself. @@ -1694,21 +1884,25 @@ llvm::DIType CGDebugInfo::CreateEnumType(const EnumDecl *ED) {    llvm::DIFile DefUnit = getOrCreateFile(ED->getLocation());    unsigned Line = getLineNumber(ED->getLocation()); -  llvm::DIDescriptor EnumContext =  +  llvm::DIDescriptor EnumContext =      getContextDescriptor(cast<Decl>(ED->getDeclContext()));    llvm::DIType ClassTy = ED->isFixed() ?      getOrCreateType(ED->getIntegerType(), DefUnit) : llvm::DIType(); -  llvm::DIType DbgTy =  +  llvm::DIType DbgTy =      DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit, Line,                                     Size, Align, EltArray, -                                   ClassTy); +                                   ClassTy, FullName);    return DbgTy;  }  static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {    Qualifiers Quals;    do { -    Quals += T.getLocalQualifiers(); +    Qualifiers InnerQuals = T.getLocalQualifiers(); +    // Qualifiers::operator+() doesn't like it if you add a Qualifier +    // that is already there. +    Quals += Qualifiers::removeCommonQualifiers(Quals, InnerQuals); +    Quals += InnerQuals;      QualType LastT = T;      switch (T->getTypeClass()) {      default: @@ -1741,21 +1935,25 @@ static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {        T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();        break;      case Type::Auto: -      T = cast<AutoType>(T)->getDeducedType(); +      QualType DT = cast<AutoType>(T)->getDeducedType(); +      if (DT.isNull()) +        return T; +      T = DT;        break;      } -     +      assert(T != LastT && "Type unwrapping failed to unwrap!");      (void)LastT;    } while (true);  } -/// getType - Get the type from the cache or return null type if it doesn't exist. +/// getType - Get the type from the cache or return null type if it doesn't +/// exist.  llvm::DIType CGDebugInfo::getTypeOrNull(QualType Ty) {    // Unwrap the type as needed for debug information.    Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext()); -   +    // Check for existing entry.    if (Ty->getTypeClass() == Type::ObjCInterface) {      llvm::Value *V = getCachedInterfaceTypeOrNull(Ty); @@ -1793,10 +1991,7 @@ llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) {    }    // Verify that any cached debug info still exists. -  if (V != 0) -    return llvm::DIType(cast<llvm::MDNode>(V)); - -  return llvm::DIType(); +  return llvm::DIType(cast_or_null<llvm::MDNode>(V));  }  /// getCachedInterfaceTypeOrNull - Get the type from the interface @@ -1824,9 +2019,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {    // Unwrap the type as needed for debug information.    Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext()); -  llvm::DIType T = getCompletedTypeOrNull(Ty); - -  if (T.Verify()) +  if (llvm::DIType T = getCompletedTypeOrNull(Ty))      return T;    // Otherwise create the type. @@ -1836,29 +2029,33 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {    // And update the type cache.    TypeCache[TyPtr] = Res; +  // FIXME: this getTypeOrNull call seems silly when we just inserted the type +  // into the cache - but getTypeOrNull has a special case for cached interface +  // types. We should probably just pull that out as a special case for the +  // "else" block below & skip the otherwise needless lookup.    llvm::DIType TC = getTypeOrNull(Ty); -  if (TC.Verify() && TC.isForwardDecl()) +  if (TC && TC.isForwardDecl())      ReplaceMap.push_back(std::make_pair(TyPtr, static_cast<llvm::Value*>(TC)));    else if (ObjCInterfaceDecl* Decl = getObjCInterfaceDecl(Ty)) {      // Interface types may have elements added to them by a      // subsequent implementation or extension, so we keep them in      // the ObjCInterfaceCache together with a checksum. Instead of -    // the (possibly) incomplete interace type, we return a forward +    // the (possibly) incomplete interface type, we return a forward      // declaration that gets RAUW'd in CGDebugInfo::finalize(). -    llvm::DenseMap<void *, std::pair<llvm::WeakVH, unsigned > > -      ::iterator it = ObjCInterfaceCache.find(TyPtr); -    if (it != ObjCInterfaceCache.end()) -      TC = llvm::DIType(cast<llvm::MDNode>(it->second.first)); -    else -      TC = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, -                                      Decl->getName(), TheCU, Unit, -                                      getLineNumber(Decl->getLocation()), -                                      TheCU.getLanguage()); +    std::pair<llvm::WeakVH, unsigned> &V = ObjCInterfaceCache[TyPtr]; +    if (V.first) +      return llvm::DIType(cast<llvm::MDNode>(V.first)); +    TC = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type, +                                    Decl->getName(), TheCU, Unit, +                                    getLineNumber(Decl->getLocation()), +                                    TheCU.getLanguage());      // Store the forward declaration in the cache. -    ObjCInterfaceCache[TyPtr] = std::make_pair(TC, Checksum(Decl)); +    V.first = TC; +    V.second = Checksum(Decl);      // Register the type for replacement in finalize().      ReplaceMap.push_back(std::make_pair(TyPtr, static_cast<llvm::Value*>(TC))); +      return TC;    } @@ -1868,19 +2065,25 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {    return Res;  } -/// Currently the checksum merely consists of the number of ivars. -unsigned CGDebugInfo::Checksum(const ObjCInterfaceDecl -                               *InterfaceDecl) { -  unsigned IvarNo = 0; -  for (const ObjCIvarDecl *Ivar = InterfaceDecl->all_declared_ivar_begin(); -       Ivar != 0; Ivar = Ivar->getNextIvar()) ++IvarNo; -  return IvarNo; +/// Currently the checksum of an interface includes the number of +/// ivars and property accessors. +unsigned CGDebugInfo::Checksum(const ObjCInterfaceDecl *ID) { +  // The assumption is that the number of ivars can only increase +  // monotonically, so it is safe to just use their current number as +  // a checksum. +  unsigned Sum = 0; +  for (const ObjCIvarDecl *Ivar = ID->all_declared_ivar_begin(); +       Ivar != 0; Ivar = Ivar->getNextIvar()) +    ++Sum; + +  return Sum;  }  ObjCInterfaceDecl *CGDebugInfo::getObjCInterfaceDecl(QualType Ty) {    switch (Ty->getTypeClass()) {    case Type::ObjCObjectPointer: -    return getObjCInterfaceDecl(cast<ObjCObjectPointerType>(Ty)->getPointeeType()); +    return getObjCInterfaceDecl(cast<ObjCObjectPointerType>(Ty) +                                    ->getPointeeType());    case Type::ObjCInterface:      return cast<ObjCInterfaceType>(Ty)->getDecl();    default: @@ -1895,7 +2098,7 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {      return CreateQualifiedType(Ty, Unit);    const char *Diag = 0; -   +    // Work out details of type.    switch (Ty->getTypeClass()) {  #define TYPE(Class, Base) @@ -1920,6 +2123,10 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {      return CreateType(cast<ComplexType>(Ty));    case Type::Pointer:      return CreateType(cast<PointerType>(Ty), Unit); +  case Type::Decayed: +    // Decayed types are just pointers in LLVM and DWARF. +    return CreateType( +        cast<PointerType>(cast<DecayedType>(Ty)->getDecayedType()), Unit);    case Type::BlockPointer:      return CreateType(cast<BlockPointerType>(Ty), Unit);    case Type::Typedef: @@ -1927,7 +2134,7 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {    case Type::Record:      return CreateType(cast<RecordType>(Ty));    case Type::Enum: -    return CreateEnumType(cast<EnumType>(Ty)->getDecl()); +    return CreateEnumType(cast<EnumType>(Ty));    case Type::FunctionProto:    case Type::FunctionNoProto:      return CreateType(cast<FunctionType>(Ty), Unit); @@ -1956,10 +2163,13 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {    case Type::TypeOf:    case Type::Decltype:    case Type::UnaryTransform: -  case Type::Auto: +  case Type::PackExpansion:      llvm_unreachable("type should have been unwrapped!"); +  case Type::Auto: +    Diag = "auto"; +    break;    } -   +    assert(Diag && "Fall through without a diagnostic?");    unsigned DiagID = CGM.getDiags().getCustomDiagID(DiagnosticsEngine::Error,                                 "debug information for %0 is not yet supported"); @@ -1970,117 +2180,119 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {  /// getOrCreateLimitedType - Get the type from the cache or create a new  /// limited type if necessary. -llvm::DIType CGDebugInfo::getOrCreateLimitedType(QualType Ty, +llvm::DIType CGDebugInfo::getOrCreateLimitedType(const RecordType *Ty,                                                   llvm::DIFile Unit) { -  if (Ty.isNull()) -    return llvm::DIType(); +  QualType QTy(Ty, 0); -  // Unwrap the type as needed for debug information. -  Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext()); - -  llvm::DIType T = getTypeOrNull(Ty); +  llvm::DICompositeType T(getTypeOrNull(QTy));    // We may have cached a forward decl when we could have created    // a non-forward decl. Go ahead and create a non-forward decl    // now. -  if (T.Verify() && !T.isForwardDecl()) return T; +  if (T && !T.isForwardDecl()) return T;    // Otherwise create the type. -  llvm::DIType Res = CreateLimitedTypeNode(Ty, Unit); +  llvm::DICompositeType Res = CreateLimitedType(Ty); -  if (T.Verify() && T.isForwardDecl()) -    ReplaceMap.push_back(std::make_pair(Ty.getAsOpaquePtr(), -                                        static_cast<llvm::Value*>(T))); +  // Propagate members from the declaration to the definition +  // CreateType(const RecordType*) will overwrite this with the members in the +  // correct order if the full type is needed. +  Res.setTypeArray(T.getTypeArray()); + +  if (T && T.isForwardDecl()) +    ReplaceMap.push_back( +        std::make_pair(QTy.getAsOpaquePtr(), static_cast<llvm::Value *>(T)));    // And update the type cache. -  TypeCache[Ty.getAsOpaquePtr()] = Res; +  TypeCache[QTy.getAsOpaquePtr()] = Res;    return Res;  }  // TODO: Currently used for context chains when limiting debug info. -llvm::DIType CGDebugInfo::CreateLimitedType(const RecordType *Ty) { +llvm::DICompositeType CGDebugInfo::CreateLimitedType(const RecordType *Ty) {    RecordDecl *RD = Ty->getDecl(); -   +    // Get overall information about the record type for the debug info.    llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());    unsigned Line = getLineNumber(RD->getLocation());    StringRef RDName = getClassName(RD); -  llvm::DIDescriptor RDContext; -  if (CGM.getCodeGenOpts().getDebugInfo() == CodeGenOptions::LimitedDebugInfo) -    RDContext = createContextChain(cast<Decl>(RD->getDeclContext())); -  else -    RDContext = getContextDescriptor(cast<Decl>(RD->getDeclContext())); +  llvm::DIDescriptor RDContext = +      getContextDescriptor(cast<Decl>(RD->getDeclContext())); + +  // If we ended up creating the type during the context chain construction, +  // just return that. +  // FIXME: this could be dealt with better if the type was recorded as +  // completed before we started this (see the CompletedTypeCache usage in +  // CGDebugInfo::CreateTypeDefinition(const RecordType*) - that would need to +  // be pushed to before context creation, but after it was known to be +  // destined for completion (might still have an issue if this caller only +  // required a declaration but the context construction ended up creating a +  // definition) +  llvm::DICompositeType T(getTypeOrNull(CGM.getContext().getRecordType(RD))); +  if (T && (!T.isForwardDecl() || !RD->getDefinition())) +      return T;    // If this is just a forward declaration, construct an appropriately    // marked node and just return it.    if (!RD->getDefinition()) -    return createRecordFwdDecl(RD, RDContext); +    return getOrCreateRecordFwdDecl(Ty, RDContext);    uint64_t Size = CGM.getContext().getTypeSize(Ty);    uint64_t Align = CGM.getContext().getTypeAlign(Ty); -  const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);    llvm::DICompositeType RealDecl; -   + +  SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU); +    if (RD->isUnion())      RealDecl = DBuilder.createUnionType(RDContext, RDName, DefUnit, Line, -                                        Size, Align, 0, llvm::DIArray()); +                                        Size, Align, 0, llvm::DIArray(), 0, +                                        FullName);    else if (RD->isClass()) {      // FIXME: This could be a struct type giving a default visibility different      // than C++ class type, but needs llvm metadata changes first.      RealDecl = DBuilder.createClassType(RDContext, RDName, DefUnit, Line,                                          Size, Align, 0, 0, llvm::DIType(),                                          llvm::DIArray(), llvm::DIType(), -                                        llvm::DIArray()); +                                        llvm::DIArray(), FullName);    } else      RealDecl = DBuilder.createStructType(RDContext, RDName, DefUnit, Line, -                                         Size, Align, 0, llvm::DIType(), llvm::DIArray()); +                                         Size, Align, 0, llvm::DIType(), +                                         llvm::DIArray(), 0, llvm::DIType(), +                                         FullName);    RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl);    TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = RealDecl; -  if (CXXDecl) { -    // A class's primary base or the class itself contains the vtable. -    llvm::DICompositeType ContainingType; -    const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); -    if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) { -      // Seek non virtual primary base root. -      while (1) { -        const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase); -        const CXXRecordDecl *PBT = BRL.getPrimaryBase(); -        if (PBT && !BRL.isPrimaryBaseVirtual()) -          PBase = PBT; -        else -          break; -      } -      ContainingType = llvm::DICompositeType( -          getOrCreateType(QualType(PBase->getTypeForDecl(), 0), DefUnit)); -    } else if (CXXDecl->isDynamicClass()) -      ContainingType = RealDecl; - -    RealDecl.setContainingType(ContainingType); -  } -  return llvm::DIType(RealDecl); +  if (const ClassTemplateSpecializationDecl *TSpecial = +          dyn_cast<ClassTemplateSpecializationDecl>(RD)) +    RealDecl.setTypeArray(llvm::DIArray(), +                          CollectCXXTemplateParams(TSpecial, DefUnit)); +  return RealDecl;  } -/// CreateLimitedTypeNode - Create a new debug type node, but only forward -/// declare composite types that haven't been processed yet. -llvm::DIType CGDebugInfo::CreateLimitedTypeNode(QualType Ty,llvm::DIFile Unit) { - -  // Work out details of type. -  switch (Ty->getTypeClass()) { -#define TYPE(Class, Base) -#define ABSTRACT_TYPE(Class, Base) -#define NON_CANONICAL_TYPE(Class, Base) -#define DEPENDENT_TYPE(Class, Base) case Type::Class: -        #include "clang/AST/TypeNodes.def" -    llvm_unreachable("Dependent types cannot show up in debug information"); +void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD, +                                        llvm::DICompositeType RealDecl) { +  // A class's primary base or the class itself contains the vtable. +  llvm::DICompositeType ContainingType; +  const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); +  if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) { +    // Seek non virtual primary base root. +    while (1) { +      const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase); +      const CXXRecordDecl *PBT = BRL.getPrimaryBase(); +      if (PBT && !BRL.isPrimaryBaseVirtual()) +        PBase = PBT; +      else +        break; +    } +    ContainingType = llvm::DICompositeType( +        getOrCreateType(QualType(PBase->getTypeForDecl(), 0), +                        getOrCreateFile(RD->getLocation()))); +  } else if (RD->isDynamicClass()) +    ContainingType = RealDecl; -  case Type::Record: -    return CreateLimitedType(cast<RecordType>(Ty)); -  default: -    return CreateTypeNode(Ty, Unit); -  } +  RealDecl.setContainingType(ContainingType);  }  /// CreateMemberType - Create new member and increase Offset by FType's size. @@ -2097,21 +2309,57 @@ llvm::DIType CGDebugInfo::CreateMemberType(llvm::DIFile Unit, QualType FType,    return Ty;  } +llvm::DIDescriptor CGDebugInfo::getDeclarationOrDefinition(const Decl *D) { +  // We only need a declaration (not a definition) of the type - so use whatever +  // we would otherwise do to get a type for a pointee. (forward declarations in +  // limited debug info, full definitions (if the type definition is available) +  // in unlimited debug info) +  if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) +    return getOrCreateType(CGM.getContext().getTypeDeclType(TD), +                           getOrCreateFile(TD->getLocation())); +  // Otherwise fall back to a fairly rudimentary cache of existing declarations. +  // This doesn't handle providing declarations (for functions or variables) for +  // entities without definitions in this TU, nor when the definition proceeds +  // the call to this function. +  // FIXME: This should be split out into more specific maps with support for +  // emitting forward declarations and merging definitions with declarations, +  // the same way as we do for types. +  llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator I = +      DeclCache.find(D->getCanonicalDecl()); +  if (I == DeclCache.end()) +    return llvm::DIDescriptor(); +  llvm::Value *V = I->second; +  return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(V)); +} +  /// getFunctionDeclaration - Return debug info descriptor to describe method  /// declaration for the given method definition.  llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) { +  if (!D || DebugKind == CodeGenOptions::DebugLineTablesOnly) +    return llvm::DISubprogram(); +    const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);    if (!FD) return llvm::DISubprogram();    // Setup context. -  getContextDescriptor(cast<Decl>(D->getDeclContext())); +  llvm::DIScope S = getContextDescriptor(cast<Decl>(D->getDeclContext()));    llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator      MI = SPCache.find(FD->getCanonicalDecl()); +  if (MI == SPCache.end()) { +    if (const CXXMethodDecl *MD = +            dyn_cast<CXXMethodDecl>(FD->getCanonicalDecl())) { +      llvm::DICompositeType T(S); +      llvm::DISubprogram SP = +          CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()), T); +      T.addMember(SP); +      return SP; +    } +  }    if (MI != SPCache.end()) {      llvm::Value *V = MI->second;      llvm::DISubprogram SP(dyn_cast_or_null<llvm::MDNode>(V)); -    if (SP.isSubprogram() && !llvm::DISubprogram(SP).isDefinition()) +    if (SP.isSubprogram() && !SP.isDefinition())        return SP;    } @@ -2123,7 +2371,7 @@ llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) {      if (MI != SPCache.end()) {        llvm::Value *V = MI->second;        llvm::DISubprogram SP(dyn_cast_or_null<llvm::MDNode>(V)); -      if (SP.isSubprogram() && !llvm::DISubprogram(SP).isDefinition()) +      if (SP.isSubprogram() && !SP.isDefinition())          return SP;      }    } @@ -2132,9 +2380,15 @@ llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) {  // getOrCreateFunctionType - Construct DIType. If it is a c++ method, include  // implicit parameter "this". -llvm::DIType CGDebugInfo::getOrCreateFunctionType(const Decl *D, -                                                  QualType FnType, -                                                  llvm::DIFile F) { +llvm::DICompositeType CGDebugInfo::getOrCreateFunctionType(const Decl *D, +                                                           QualType FnType, +                                                           llvm::DIFile F) { +  if (!D || DebugKind == CodeGenOptions::DebugLineTablesOnly) +    // Create fake but valid subroutine type. Otherwise +    // llvm::DISubprogram::Verify() would return false, and +    // subprogram DIE will miss DW_AT_decl_file and +    // DW_AT_decl_line fields. +    return DBuilder.createSubroutineType(F, DBuilder.getOrCreateArray(None));    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))      return getOrCreateMethodType(Method, F); @@ -2143,7 +2397,14 @@ llvm::DIType CGDebugInfo::getOrCreateFunctionType(const Decl *D,      SmallVector<llvm::Value *, 16> Elts;      // First element is always return type. For 'void' functions it is NULL. -    Elts.push_back(getOrCreateType(OMethod->getResultType(), F)); +    QualType ResultTy = OMethod->getResultType(); + +    // Replace the instancetype keyword with the actual type. +    if (ResultTy == CGM.getContext().getObjCInstanceType()) +      ResultTy = CGM.getContext().getPointerType( +        QualType(OMethod->getClassInterface()->getTypeForDecl(), 0)); + +    Elts.push_back(getOrCreateType(ResultTy, F));      // "self" pointer is always first argument.      QualType SelfDeclTy = OMethod->getSelfDecl()->getType();      llvm::DIType SelfTy = getOrCreateType(SelfDeclTy, F); @@ -2152,14 +2413,14 @@ llvm::DIType CGDebugInfo::getOrCreateFunctionType(const Decl *D,      llvm::DIType CmdTy = getOrCreateType(OMethod->getCmdDecl()->getType(), F);      Elts.push_back(DBuilder.createArtificialType(CmdTy));      // Get rest of the arguments. -    for (ObjCMethodDecl::param_const_iterator PI = OMethod->param_begin(),  +    for (ObjCMethodDecl::param_const_iterator PI = OMethod->param_begin(),             PE = OMethod->param_end(); PI != PE; ++PI)        Elts.push_back(getOrCreateType((*PI)->getType(), F));      llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);      return DBuilder.createSubroutineType(F, EltTypeArray);    } -  return getOrCreateType(FnType, F); +  return llvm::DICompositeType(getOrCreateType(FnType, F));  }  /// EmitFunctionStart - Constructs the debug code for entering a function. @@ -2187,7 +2448,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,    llvm::DIArray TParamsArray;    if (!HasDecl) {      // Use llvm function name. -    Name = Fn->getName(); +    LinkageName = Fn->getName();    } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {      // If there is a DISubprogram for this function available then use it.      llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator @@ -2214,16 +2475,16 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,      if (LinkageName == Name ||          (!CGM.getCodeGenOpts().EmitGcovArcs &&           !CGM.getCodeGenOpts().EmitGcovNotes && -         CGM.getCodeGenOpts().getDebugInfo() <= CodeGenOptions::DebugLineTablesOnly)) +         DebugKind <= CodeGenOptions::DebugLineTablesOnly))        LinkageName = StringRef(); -    if (CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo) { +    if (DebugKind >= CodeGenOptions::LimitedDebugInfo) {        if (const NamespaceDecl *NSDecl = -          dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext())) +              dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext()))          FDContext = getOrCreateNameSpace(NSDecl);        else if (const RecordDecl *RDecl = -               dyn_cast_or_null<RecordDecl>(FD->getDeclContext())) -        FDContext = getContextDescriptor(cast<Decl>(RDecl->getDeclContext())); +                   dyn_cast_or_null<RecordDecl>(FD->getDeclContext())) +        FDContext = getContextDescriptor(cast<Decl>(RDecl));        // Collect template parameters.        TParamsArray = CollectFunctionTemplateParams(FD, Unit); @@ -2243,28 +2504,15 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,    if (!HasDecl || D->isImplicit())      Flags |= llvm::DIDescriptor::FlagArtificial; -  llvm::DIType DIFnType; -  llvm::DISubprogram SPDecl; -  if (HasDecl && -      CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo) { -    DIFnType = getOrCreateFunctionType(D, FnType, Unit); -    SPDecl = getFunctionDeclaration(D); -  } else { -    // Create fake but valid subroutine type. Otherwise -    // llvm::DISubprogram::Verify() would return false, and -    // subprogram DIE will miss DW_AT_decl_file and -    // DW_AT_decl_line fields. -    SmallVector<llvm::Value*, 16> Elts; -    llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts); -    DIFnType = DBuilder.createSubroutineType(Unit, EltTypeArray); -  } -  llvm::DISubprogram SP; -  SP = DBuilder.createFunction(FDContext, Name, LinkageName, Unit, -                               LineNo, DIFnType, -                               Fn->hasInternalLinkage(), true/*definition*/, -                               getLineNumber(CurLoc), Flags, -                               CGM.getLangOpts().Optimize, -                               Fn, TParamsArray, SPDecl); +  llvm::DISubprogram SP = +      DBuilder.createFunction(FDContext, Name, LinkageName, Unit, LineNo, +                              getOrCreateFunctionType(D, FnType, Unit), +                              Fn->hasInternalLinkage(), true /*definition*/, +                              getLineNumber(CurLoc), Flags, +                              CGM.getLangOpts().Optimize, Fn, TParamsArray, +                              getFunctionDeclaration(D)); +  if (HasDecl) +    DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(SP)));    // Push function on region stack.    llvm::MDNode *SPN = SP; @@ -2274,10 +2522,10 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,  }  /// EmitLocation - Emit metadata to indicate a change in line/column -/// information in the source file. +/// information in the source file. If the location is invalid, the +/// previous location will be reused.  void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc,                                 bool ForceColumnInfo) { -      // Update our current location    setLocation(Loc); @@ -2292,7 +2540,7 @@ void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc,          Builder.getCurrentDebugLocation().getScope(CGM.getLLVMContext()) ==            LexicalBlockStack.back())        return; -   +    // Update last state.    PrevLoc = CurLoc; @@ -2319,7 +2567,8 @@ void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) {  /// EmitLexicalBlockStart - Constructs the debug code for entering a declarative  /// region - beginning of a DW_TAG_lexical_block. -void CGDebugInfo::EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc) { +void CGDebugInfo::EmitLexicalBlockStart(CGBuilderTy &Builder, +                                        SourceLocation Loc) {    // Set our current location.    setLocation(Loc); @@ -2334,7 +2583,8 @@ void CGDebugInfo::EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc  /// EmitLexicalBlockEnd - Constructs the debug code for exiting a declarative  /// region - end of a DW_TAG_lexical_block. -void CGDebugInfo::EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc) { +void CGDebugInfo::EmitLexicalBlockEnd(CGBuilderTy &Builder, +                                      SourceLocation Loc) {    assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");    // Provide an entry in the line table for the end of the block. @@ -2355,7 +2605,7 @@ void CGDebugInfo::EmitFunctionEnd(CGBuilderTy &Builder) {    FnBeginRegionCount.pop_back();  } -// EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.   +// EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.  // See BuildByRefType.  llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD,                                                         uint64_t *XOffset) { @@ -2364,9 +2614,9 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD,    QualType FType;    uint64_t FieldSize, FieldOffset;    unsigned FieldAlign; -   +    llvm::DIFile Unit = getOrCreateFile(VD->getLocation()); -  QualType Type = VD->getType();   +  QualType Type = VD->getType();    FieldOffset = 0;    FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy); @@ -2388,21 +2638,23 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD,    Qualifiers::ObjCLifetime Lifetime;    if (CGM.getContext().getByrefLifetime(Type,                                          Lifetime, HasByrefExtendedLayout) -      && HasByrefExtendedLayout) +      && HasByrefExtendedLayout) { +    FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);      EltTys.push_back(CreateMemberType(Unit, FType,                                        "__byref_variable_layout",                                        &FieldOffset)); -   +  } +    CharUnits Align = CGM.getContext().getDeclAlign(VD);    if (Align > CGM.getContext().toCharUnitsFromBits(          CGM.getTarget().getPointerAlign(0))) { -    CharUnits FieldOffsetInBytes  +    CharUnits FieldOffsetInBytes        = CGM.getContext().toCharUnitsFromBits(FieldOffset);      CharUnits AlignedOffsetInBytes        = FieldOffsetInBytes.RoundUpToAlignment(Align);      CharUnits NumPaddingBytes        = AlignedOffsetInBytes - FieldOffsetInBytes; -     +      if (NumPaddingBytes.isPositive()) {        llvm::APInt pad(32, NumPaddingBytes.getQuantity());        FType = CGM.getContext().getConstantArrayType(CGM.getContext().CharTy, @@ -2410,40 +2662,45 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD,        EltTys.push_back(CreateMemberType(Unit, FType, "", &FieldOffset));      }    } -   +    FType = Type;    llvm::DIType FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);    FieldSize = CGM.getContext().getTypeSize(FType);    FieldAlign = CGM.getContext().toBits(Align); -  *XOffset = FieldOffset;   +  *XOffset = FieldOffset;    FieldTy = DBuilder.createMemberType(Unit, VD->getName(), Unit,                                        0, FieldSize, FieldAlign,                                        FieldOffset, 0, FieldTy);    EltTys.push_back(FieldTy);    FieldOffset += FieldSize; -   +    llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys); -   +    unsigned Flags = llvm::DIDescriptor::FlagBlockByrefStruct; -   +    return DBuilder.createStructType(Unit, "", Unit, 0, FieldOffset, 0, Flags,                                     llvm::DIType(), Elements);  }  /// EmitDeclare - Emit local variable declaration debug info.  void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag, -                              llvm::Value *Storage,  +                              llvm::Value *Storage,                                unsigned ArgNo, CGBuilderTy &Builder) { -  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo); +  assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);    assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); -  llvm::DIFile Unit = getOrCreateFile(VD->getLocation()); +  bool Unwritten = +      VD->isImplicit() || (isa<Decl>(VD->getDeclContext()) && +                           cast<Decl>(VD->getDeclContext())->isImplicit()); +  llvm::DIFile Unit; +  if (!Unwritten) +    Unit = getOrCreateFile(VD->getLocation());    llvm::DIType Ty;    uint64_t XOffset = 0;    if (VD->hasAttr<BlocksAttr>())      Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset); -  else  +  else      Ty = getOrCreateType(VD->getType(), Unit);    // If there is no debug info for this type then do not emit debug info @@ -2451,24 +2708,13 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,    if (!Ty)      return; -  if (llvm::Argument *Arg = dyn_cast<llvm::Argument>(Storage)) { -    // If Storage is an aggregate returned as 'sret' then let debugger know -    // about this. -    if (Arg->hasStructRetAttr()) -      Ty = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type, Ty); -    else if (CXXRecordDecl *Record = VD->getType()->getAsCXXRecordDecl()) { -      // If an aggregate variable has non trivial destructor or non trivial copy -      // constructor than it is pass indirectly. Let debug info know about this -      // by using reference of the aggregate type as a argument type. -      if (Record->hasNonTrivialCopyConstructor() || -          !Record->hasTrivialDestructor()) -        Ty = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type, Ty); -    } -  } -          // Get location information. -  unsigned Line = getLineNumber(VD->getLocation()); -  unsigned Column = getColumnNumber(VD->getLocation()); +  unsigned Line = 0; +  unsigned Column = 0; +  if (!Unwritten) { +    Line = getLineNumber(VD->getLocation()); +    Column = getColumnNumber(VD->getLocation()); +  }    unsigned Flags = 0;    if (VD->isImplicit())      Flags |= llvm::DIDescriptor::FlagArtificial; @@ -2479,6 +2725,10 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,    // otherwise it is 'self' or 'this'.    if (isa<ImplicitParamDecl>(VD) && ArgNo == 1)      Flags |= llvm::DIDescriptor::FlagObjectPointer; +  if (llvm::Argument *Arg = dyn_cast<llvm::Argument>(Storage)) +    if (Arg->getType()->isPointerTy() && !Arg->hasByValAttr() && +        !VD->getType()->isPointerType()) +      Flags |= llvm::DIDescriptor::FlagIndirectVariable;    llvm::MDNode *Scope = LexicalBlockStack.back(); @@ -2501,33 +2751,18 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,        // Create the descriptor for the variable.        llvm::DIVariable D = -        DBuilder.createComplexVariable(Tag,  +        DBuilder.createComplexVariable(Tag,                                         llvm::DIDescriptor(Scope),                                         VD->getName(), Unit, Line, Ty,                                         addr, ArgNo); -       -      // Insert an llvm.dbg.declare into the current block. -      llvm::Instruction *Call = -        DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock()); -      Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope)); -      return; -    } else if (isa<VariableArrayType>(VD->getType())) { -      // These are "complex" variables in that they need an op_deref. -      // Create the descriptor for the variable. -      llvm::Value *Addr = llvm::ConstantInt::get(CGM.Int64Ty, -                                                 llvm::DIBuilder::OpDeref); -      llvm::DIVariable D = -        DBuilder.createComplexVariable(Tag, -                                       llvm::DIDescriptor(Scope), -                                       Name, Unit, Line, Ty, -                                       Addr, ArgNo);        // Insert an llvm.dbg.declare into the current block.        llvm::Instruction *Call =          DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock());        Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));        return; -    } +    } else if (isa<VariableArrayType>(VD->getType())) +      Flags |= llvm::DIDescriptor::FlagIndirectVariable;    } else if (const RecordType *RT = dyn_cast<RecordType>(VD->getType())) {      // If VD is an anonymous union then Storage represents value for      // all union fields. @@ -2539,18 +2774,18 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,          FieldDecl *Field = *I;          llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);          StringRef FieldName = Field->getName(); -           +          // Ignore unnamed fields. Do not ignore unnamed records.          if (FieldName.empty() && !isa<RecordType>(Field->getType()))            continue; -           +          // Use VarDecl's Tag, Scope and Line number.          llvm::DIVariable D =            DBuilder.createLocalVariable(Tag, llvm::DIDescriptor(Scope), -                                       FieldName, Unit, Line, FieldTy,  +                                       FieldName, Unit, Line, FieldTy,                                         CGM.getLangOpts().Optimize, Flags,                                         ArgNo); -           +          // Insert an llvm.dbg.declare into the current block.          llvm::Instruction *Call =            DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock()); @@ -2575,7 +2810,7 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,  void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD,                                              llvm::Value *Storage,                                              CGBuilderTy &Builder) { -  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo); +  assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);    EmitDeclare(VD, llvm::dwarf::DW_TAG_auto_variable, Storage, 0, Builder);  } @@ -2585,9 +2820,10 @@ void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD,  /// never happen though, since creating a type for the implicit self  /// argument implies that we already parsed the interface definition  /// and the ivar declarations in the implementation. -llvm::DIType CGDebugInfo::CreateSelfType(const QualType &QualTy, llvm::DIType Ty) { +llvm::DIType CGDebugInfo::CreateSelfType(const QualType &QualTy, +                                         llvm::DIType Ty) {    llvm::DIType CachedTy = getTypeOrNull(QualTy); -  if (CachedTy.Verify()) Ty = CachedTy; +  if (CachedTy) Ty = CachedTy;    else DEBUG(llvm::dbgs() << "No cached type for self.");    return DBuilder.createObjectPointerType(Ty);  } @@ -2596,20 +2832,20 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(const VarDecl *VD,                                                      llvm::Value *Storage,                                                      CGBuilderTy &Builder,                                                   const CGBlockInfo &blockInfo) { -  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo); +  assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);    assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); -   +    if (Builder.GetInsertBlock() == 0)      return; -   +    bool isByRef = VD->hasAttr<BlocksAttr>(); -   +    uint64_t XOffset = 0;    llvm::DIFile Unit = getOrCreateFile(VD->getLocation());    llvm::DIType Ty;    if (isByRef)      Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset); -  else  +  else      Ty = getOrCreateType(VD->getType(), Unit);    // Self is passed along as an implicit non-arg variable in a @@ -2649,7 +2885,7 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(const VarDecl *VD,    // Create the descriptor for the variable.    llvm::DIVariable D = -    DBuilder.createComplexVariable(llvm::dwarf::DW_TAG_auto_variable,  +    DBuilder.createComplexVariable(llvm::dwarf::DW_TAG_auto_variable,                                     llvm::DIDescriptor(LexicalBlockStack.back()),                                     VD->getName(), Unit, Line, Ty, addr); @@ -2665,7 +2901,7 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(const VarDecl *VD,  void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *VD, llvm::Value *AI,                                             unsigned ArgNo,                                             CGBuilderTy &Builder) { -  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo); +  assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);    EmitDeclare(VD, llvm::dwarf::DW_TAG_arg_variable, AI, ArgNo, Builder);  } @@ -2683,7 +2919,7 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,                                                         llvm::Value *Arg,                                                         llvm::Value *LocalAddr,                                                         CGBuilderTy &Builder) { -  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo); +  assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);    ASTContext &C = CGM.getContext();    const BlockDecl *blockDecl = block.getBlockDecl(); @@ -2692,7 +2928,7 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,    llvm::DIFile tunit = getOrCreateFile(loc);    unsigned line = getLineNumber(loc);    unsigned column = getColumnNumber(loc); -   +    // Build the debug-info type for the block literal.    getContextDescriptor(cast<Decl>(blockDecl->getDeclContext())); @@ -2812,7 +3048,7 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,    // Create the descriptor for the parameter.    llvm::DIVariable debugVar =      DBuilder.createLocalVariable(llvm::dwarf::DW_TAG_arg_variable, -                                 llvm::DIDescriptor(scope),  +                                 llvm::DIDescriptor(scope),                                   Arg->getName(), tunit, line, type,                                   CGM.getLangOpts().Optimize, flags,                                   cast<llvm::Argument>(Arg)->getArgNo() + 1); @@ -2831,25 +3067,32 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,    DbgDecl->setDebugLoc(llvm::DebugLoc::get(line, column, scope));  } -/// getStaticDataMemberDeclaration - If D is an out-of-class definition of -/// a static data member of a class, find its corresponding in-class -/// declaration. -llvm::DIDerivedType CGDebugInfo::getStaticDataMemberDeclaration(const Decl *D) { -  if (cast<VarDecl>(D)->isStaticDataMember()) { -    llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator -      MI = StaticDataMemberCache.find(D->getCanonicalDecl()); -    if (MI != StaticDataMemberCache.end()) -      // Verify the info still exists. -      if (llvm::Value *V = MI->second) -        return llvm::DIDerivedType(cast<llvm::MDNode>(V)); -  } -  return llvm::DIDerivedType(); +/// If D is an out-of-class definition of a static data member of a class, find +/// its corresponding in-class declaration. +llvm::DIDerivedType +CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D) { +  if (!D->isStaticDataMember()) +    return llvm::DIDerivedType(); +  llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator MI = +      StaticDataMemberCache.find(D->getCanonicalDecl()); +  if (MI != StaticDataMemberCache.end()) { +    assert(MI->second && "Static data member declaration should still exist"); +    return llvm::DIDerivedType(cast<llvm::MDNode>(MI->second)); +  } + +  // If the member wasn't found in the cache, lazily construct and add it to the +  // type (used when a limited form of the type is emitted). +  llvm::DICompositeType Ctxt( +      getContextDescriptor(cast<Decl>(D->getDeclContext()))); +  llvm::DIDerivedType T = CreateRecordStaticField(D, Ctxt); +  Ctxt.addMember(T); +  return T;  }  /// EmitGlobalVariable - Emit information about a global variable.  void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,                                       const VarDecl *D) { -  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo); +  assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);    // Create global variable debug descriptor.    llvm::DIFile Unit = getOrCreateFile(D->getLocation());    unsigned LineNo = getLineNumber(D->getLocation()); @@ -2873,18 +3116,19 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,      LinkageName = Var->getName();    if (LinkageName == DeclName)      LinkageName = StringRef(); -  llvm::DIDescriptor DContext =  +  llvm::DIDescriptor DContext =      getContextDescriptor(dyn_cast<Decl>(D->getDeclContext())); -  DBuilder.createStaticVariable(DContext, DeclName, LinkageName, -                                Unit, LineNo, getOrCreateType(T, Unit), -                                Var->hasInternalLinkage(), Var, -                                getStaticDataMemberDeclaration(D)); +  llvm::DIGlobalVariable GV = DBuilder.createStaticVariable( +      DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit), +      Var->hasInternalLinkage(), Var, +      getOrCreateStaticDataMemberDeclarationOrNull(D)); +  DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(GV)));  }  /// EmitGlobalVariable - Emit information about an objective-c interface.  void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,                                       ObjCInterfaceDecl *ID) { -  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo); +  assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);    // Create global variable debug descriptor.    llvm::DIFile Unit = getOrCreateFile(ID->getLocation());    unsigned LineNo = getLineNumber(ID->getLocation()); @@ -2908,9 +3152,9 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,  }  /// EmitGlobalVariable - Emit global variable's debug info. -void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD,  +void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD,                                       llvm::Constant *Init) { -  assert(CGM.getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo); +  assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);    // Create the descriptor for the variable.    llvm::DIFile Unit = getOrCreateFile(VD->getLocation());    StringRef Name = VD->getName(); @@ -2923,34 +3167,79 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD,    // Do not use DIGlobalVariable for enums.    if (Ty.getTag() == llvm::dwarf::DW_TAG_enumeration_type)      return; -  DBuilder.createStaticVariable(Unit, Name, Name, Unit, -                                getLineNumber(VD->getLocation()), -                                Ty, true, Init, -                                getStaticDataMemberDeclaration(VD)); +  llvm::DIGlobalVariable GV = DBuilder.createStaticVariable( +      Unit, Name, Name, Unit, getLineNumber(VD->getLocation()), Ty, true, Init, +      getOrCreateStaticDataMemberDeclarationOrNull(cast<VarDecl>(VD))); +  DeclCache.insert(std::make_pair(VD->getCanonicalDecl(), llvm::WeakVH(GV))); +} + +llvm::DIScope CGDebugInfo::getCurrentContextDescriptor(const Decl *D) { +  if (!LexicalBlockStack.empty()) +    return llvm::DIScope(LexicalBlockStack.back()); +  return getContextDescriptor(D);  }  void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) { -  llvm::DIScope Scope = -      LexicalBlockStack.empty() -          ? getContextDescriptor(cast<Decl>(UD.getDeclContext())) -          : llvm::DIScope(LexicalBlockStack.back()); +  if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo) +    return;    DBuilder.createImportedModule( -      Scope, getOrCreateNameSpace(UD.getNominatedNamespace()), +      getCurrentContextDescriptor(cast<Decl>(UD.getDeclContext())), +      getOrCreateNameSpace(UD.getNominatedNamespace()),        getLineNumber(UD.getLocation()));  } +void CGDebugInfo::EmitUsingDecl(const UsingDecl &UD) { +  if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo) +    return; +  assert(UD.shadow_size() && +         "We shouldn't be codegening an invalid UsingDecl containing no decls"); +  // Emitting one decl is sufficient - debuggers can detect that this is an +  // overloaded name & provide lookup for all the overloads. +  const UsingShadowDecl &USD = **UD.shadow_begin(); +  if (llvm::DIDescriptor Target = +          getDeclarationOrDefinition(USD.getUnderlyingDecl())) +    DBuilder.createImportedDeclaration( +        getCurrentContextDescriptor(cast<Decl>(USD.getDeclContext())), Target, +        getLineNumber(USD.getLocation())); +} + +llvm::DIImportedEntity +CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) { +  if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo) +    return llvm::DIImportedEntity(0); +  llvm::WeakVH &VH = NamespaceAliasCache[&NA]; +  if (VH) +    return llvm::DIImportedEntity(cast<llvm::MDNode>(VH)); +  llvm::DIImportedEntity R(0); +  if (const NamespaceAliasDecl *Underlying = +          dyn_cast<NamespaceAliasDecl>(NA.getAliasedNamespace())) +    // This could cache & dedup here rather than relying on metadata deduping. +    R = DBuilder.createImportedModule( +        getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())), +        EmitNamespaceAlias(*Underlying), getLineNumber(NA.getLocation()), +        NA.getName()); +  else +    R = DBuilder.createImportedModule( +        getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())), +        getOrCreateNameSpace(cast<NamespaceDecl>(NA.getAliasedNamespace())), +        getLineNumber(NA.getLocation()), NA.getName()); +  VH = R; +  return R; +} +  /// getOrCreateNamesSpace - Return namespace descriptor for the given  /// namespace decl. -llvm::DINameSpace  +llvm::DINameSpace  CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl) { -  llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH>::iterator I =  +  NSDecl = NSDecl->getCanonicalDecl(); +  llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH>::iterator I =      NameSpaceCache.find(NSDecl);    if (I != NameSpaceCache.end())      return llvm::DINameSpace(cast<llvm::MDNode>(I->second)); -   +    unsigned LineNo = getLineNumber(NSDecl->getLocation());    llvm::DIFile FileD = getOrCreateFile(NSDecl->getLocation()); -  llvm::DIDescriptor Context =  +  llvm::DIDescriptor Context =      getContextDescriptor(dyn_cast<Decl>(NSDecl->getDeclContext()));    llvm::DINameSpace NS =      DBuilder.createNameSpace(Context, NSDecl->getName(), FileD, LineNo); @@ -2965,7 +3254,7 @@ void CGDebugInfo::finalize() {      // Verify that the debug info still exists.      if (llvm::Value *V = VI->second)        Ty = llvm::DIType(cast<llvm::MDNode>(V)); -     +      llvm::DenseMap<void *, llvm::WeakVH>::iterator it =        TypeCache.find(VI->first);      if (it != TypeCache.end()) { @@ -2974,7 +3263,7 @@ void CGDebugInfo::finalize() {          RepTy = llvm::DIType(cast<llvm::MDNode>(V));      } -    if (Ty.Verify() && Ty.isForwardDecl() && RepTy.Verify()) +    if (Ty && Ty.isForwardDecl() && RepTy)        Ty.replaceAllUsesWith(RepTy);    } diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index 4080492a1c68f..0ca274f568818 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -18,6 +18,7 @@  #include "clang/AST/Expr.h"  #include "clang/AST/Type.h"  #include "clang/Basic/SourceLocation.h" +#include "clang/Frontend/CodeGenOptions.h"  #include "llvm/ADT/DenseMap.h"  #include "llvm/DIBuilder.h"  #include "llvm/DebugInfo.h" @@ -35,6 +36,7 @@ namespace clang {    class ObjCIvarDecl;    class ClassTemplateSpecializationDecl;    class GlobalDecl; +  class UsingDecl;  namespace CodeGen {    class CodeGenModule; @@ -45,7 +47,10 @@ namespace CodeGen {  /// and is responsible for emitting to llvm globals or pass directly to  /// the backend.  class CGDebugInfo { +  friend class NoLocation; +  friend class ArtificialLocation;    CodeGenModule &CGM; +  const CodeGenOptions::DebugInfoKind DebugKind;    llvm::DIBuilder DBuilder;    llvm::DICompileUnit TheCU;    SourceLocation CurLoc, PrevLoc; @@ -57,14 +62,14 @@ class CGDebugInfo {    llvm::DIType OCLImage2dDITy, OCLImage2dArrayDITy;    llvm::DIType OCLImage3dDITy;    llvm::DIType OCLEventDITy; -   +  llvm::DIType BlockLiteralGeneric; +    /// TypeCache - Cache of previously constructed Types.    llvm::DenseMap<void *, llvm::WeakVH> TypeCache;    /// ObjCInterfaceCache - Cache of previously constructed interfaces    /// which may change. Storing a pair of DIType and checksum. -  llvm::DenseMap<void *, std::pair<llvm::WeakVH, unsigned > > -    ObjCInterfaceCache; +  llvm::DenseMap<void *, std::pair<llvm::WeakVH, unsigned> > ObjCInterfaceCache;    /// RetainedTypes - list of interfaces we want to keep even if orphaned.    std::vector<void *> RetainedTypes; @@ -76,9 +81,6 @@ class CGDebugInfo {    /// compilation.    std::vector<std::pair<void *, llvm::WeakVH> >ReplaceMap; -  bool BlockLiteralGenericSet; -  llvm::DIType BlockLiteralGeneric; -    // LexicalBlockStack - Keep track of our current nested lexical block.    std::vector<llvm::TrackingVH<llvm::MDNode> > LexicalBlockStack;    llvm::DenseMap<const Decl *, llvm::WeakVH> RegionMap; @@ -94,22 +96,28 @@ class CGDebugInfo {    llvm::DenseMap<const char *, llvm::WeakVH> DIFileCache;    llvm::DenseMap<const FunctionDecl *, llvm::WeakVH> SPCache; +  /// \brief Cache declarations relevant to DW_TAG_imported_declarations (C++ +  /// using declarations) that aren't covered by other more specific caches. +  llvm::DenseMap<const Decl *, llvm::WeakVH> DeclCache;    llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH> NameSpaceCache; +  llvm::DenseMap<const NamespaceAliasDecl *, llvm::WeakVH> NamespaceAliasCache;    llvm::DenseMap<const Decl *, llvm::WeakVH> StaticDataMemberCache;    /// Helper functions for getOrCreateType.    unsigned Checksum(const ObjCInterfaceDecl *InterfaceDecl);    llvm::DIType CreateType(const BuiltinType *Ty);    llvm::DIType CreateType(const ComplexType *Ty); -  llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile F); -  llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile F); +  llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile Fg); +  llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile Fg);    llvm::DIType CreateType(const ObjCObjectPointerType *Ty,                            llvm::DIFile F);    llvm::DIType CreateType(const PointerType *Ty, llvm::DIFile F);    llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DIFile F);    llvm::DIType CreateType(const FunctionType *Ty, llvm::DIFile F); -  llvm::DIType CreateType(const RecordType *Ty); -  llvm::DIType CreateLimitedType(const RecordType *Ty); +  llvm::DIType CreateType(const RecordType *Tyg); +  llvm::DIType CreateTypeDefinition(const RecordType *Ty); +  llvm::DICompositeType CreateLimitedType(const RecordType *Ty); +  void CollectContainingType(const CXXRecordDecl *RD, llvm::DICompositeType CT);    llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F);    llvm::DIType CreateType(const ObjCObjectType *Ty, llvm::DIFile F);    llvm::DIType CreateType(const VectorType *Ty, llvm::DIFile F); @@ -118,19 +126,19 @@ class CGDebugInfo {    llvm::DIType CreateType(const RValueReferenceType *Ty, llvm::DIFile Unit);    llvm::DIType CreateType(const MemberPointerType *Ty, llvm::DIFile F);    llvm::DIType CreateType(const AtomicType *Ty, llvm::DIFile F); -  llvm::DIType CreateEnumType(const EnumDecl *ED); +  llvm::DIType CreateEnumType(const EnumType *Ty);    llvm::DIType CreateSelfType(const QualType &QualTy, llvm::DIType Ty);    llvm::DIType getTypeOrNull(const QualType);    llvm::DIType getCompletedTypeOrNull(const QualType); -  llvm::DIType getOrCreateMethodType(const CXXMethodDecl *Method, -                                     llvm::DIFile F); -  llvm::DIType getOrCreateInstanceMethodType( +  llvm::DICompositeType getOrCreateMethodType(const CXXMethodDecl *Method, +                                              llvm::DIFile F); +  llvm::DICompositeType getOrCreateInstanceMethodType(        QualType ThisPtr, const FunctionProtoType *Func, llvm::DIFile Unit); -  llvm::DIType getOrCreateFunctionType(const Decl *D, QualType FnType, -                                       llvm::DIFile F); +  llvm::DICompositeType getOrCreateFunctionType(const Decl *D, QualType FnType, +                                                llvm::DIFile F);    llvm::DIType getOrCreateVTablePtrType(llvm::DIFile F);    llvm::DINameSpace getOrCreateNameSpace(const NamespaceDecl *N); -  llvm::DIType CreatePointeeType(QualType PointeeTy, llvm::DIFile F); +  llvm::DIType getOrCreateTypeDeclaration(QualType PointeeTy, llvm::DIFile F);    llvm::DIType CreatePointerLikeType(unsigned Tag,                                       const Type *Ty, QualType PointeeTy,                                       llvm::DIFile F); @@ -141,29 +149,24 @@ class CGDebugInfo {    llvm::DISubprogram CreateCXXMemberFunction(const CXXMethodDecl *Method,                                               llvm::DIFile F,                                               llvm::DIType RecordTy); -   +    void CollectCXXMemberFunctions(const CXXRecordDecl *Decl,                                   llvm::DIFile F,                                   SmallVectorImpl<llvm::Value *> &E,                                   llvm::DIType T); -  void CollectCXXFriends(const CXXRecordDecl *Decl, -                       llvm::DIFile F, -                       SmallVectorImpl<llvm::Value *> &EltTys, -                       llvm::DIType RecordTy); -    void CollectCXXBases(const CXXRecordDecl *Decl,                         llvm::DIFile F,                         SmallVectorImpl<llvm::Value *> &EltTys,                         llvm::DIType RecordTy); -   +    llvm::DIArray    CollectTemplateParams(const TemplateParameterList *TPList, -                        const TemplateArgumentList &TAList, +                        ArrayRef<TemplateArgument> TAList,                          llvm::DIFile Unit);    llvm::DIArray    CollectFunctionTemplateParams(const FunctionDecl *FD, llvm::DIFile Unit); -  llvm::DIArray  +  llvm::DIArray    CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TS,                             llvm::DIFile F); @@ -171,22 +174,21 @@ class CGDebugInfo {                                 uint64_t sizeInBitsOverride, SourceLocation loc,                                 AccessSpecifier AS, uint64_t offsetInBits,                                 llvm::DIFile tunit, -                               llvm::DIDescriptor scope); +                               llvm::DIScope scope);    // Helpers for collecting fields of a record.    void CollectRecordLambdaFields(const CXXRecordDecl *CXXDecl,                                   SmallVectorImpl<llvm::Value *> &E,                                   llvm::DIType RecordTy); -  void CollectRecordStaticField(const VarDecl *Var, -                                SmallVectorImpl<llvm::Value *> &E, -                                llvm::DIType RecordTy); +  llvm::DIDerivedType CreateRecordStaticField(const VarDecl *Var, +                                              llvm::DIType RecordTy);    void CollectRecordNormalField(const FieldDecl *Field, uint64_t OffsetInBits,                                  llvm::DIFile F,                                  SmallVectorImpl<llvm::Value *> &E,                                  llvm::DIType RecordTy);    void CollectRecordFields(const RecordDecl *Decl, llvm::DIFile F,                             SmallVectorImpl<llvm::Value *> &E, -                           llvm::DIType RecordTy); +                           llvm::DICompositeType RecordTy);    void CollectVTableInfo(const CXXRecordDecl *Decl,                           llvm::DIFile F, @@ -195,7 +197,7 @@ class CGDebugInfo {    // CreateLexicalBlock - Create a new lexical block node and push it on    // the stack.    void CreateLexicalBlock(SourceLocation Loc); -   +  public:    CGDebugInfo(CodeGenModule &CGM);    ~CGDebugInfo(); @@ -206,6 +208,9 @@ public:    /// invalid it is ignored.    void setLocation(SourceLocation Loc); +  /// getLocation - Return the current source location. +  SourceLocation getLocation() const { return CurLoc; } +    /// EmitLocation - Emit metadata to indicate a change in line/column    /// information in the source file.    /// \param ForceColumnInfo  Assume DebugColumnInfo option is true. @@ -265,20 +270,30 @@ public:    /// \brief - Emit C++ using directive.    void EmitUsingDirective(const UsingDirectiveDecl &UD); -  /// getOrCreateRecordType - Emit record type's standalone debug info.  +  /// \brief - Emit C++ using declaration. +  void EmitUsingDecl(const UsingDecl &UD); + +  /// \brief - Emit C++ namespace alias. +  llvm::DIImportedEntity EmitNamespaceAlias(const NamespaceAliasDecl &NA); + +  /// getOrCreateRecordType - Emit record type's standalone debug info.    llvm::DIType getOrCreateRecordType(QualType Ty, SourceLocation L);    /// getOrCreateInterfaceType - Emit an objective c interface type standalone    /// debug info.    llvm::DIType getOrCreateInterfaceType(QualType Ty, -					SourceLocation Loc); +                                        SourceLocation Loc); + +  void completeType(const RecordDecl *RD); +  void completeRequiredType(const RecordDecl *RD); +  void completeClassData(const RecordDecl *RD);  private:    /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.    void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,                     unsigned ArgNo, CGBuilderTy &Builder); -  // EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.   +  // EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.    // See BuildByRefType.    llvm::DIType EmitTypeForVarWithBlocksAttr(const VarDecl *VD,                                              uint64_t *OffSet); @@ -286,10 +301,12 @@ private:    /// getContextDescriptor - Get context info for the decl.    llvm::DIScope getContextDescriptor(const Decl *Decl); -  /// createRecordFwdDecl - Create a forward decl for a RecordType in a given -  /// context. -  llvm::DIType createRecordFwdDecl(const RecordDecl *, llvm::DIDescriptor); -   +  llvm::DIScope getCurrentContextDescriptor(const Decl *Decl); + +  /// \brief Create a forward decl for a RecordType in a given context. +  llvm::DICompositeType getOrCreateRecordFwdDecl(const RecordType *, +                                                 llvm::DIDescriptor); +    /// createContextChain - Create a set of decls for the context chain.    llvm::DIDescriptor createContextChain(const Decl *Decl); @@ -299,7 +316,7 @@ private:    /// CreateCompileUnit - Create new compile unit.    void CreateCompileUnit(); -  /// getOrCreateFile - Get the file debug info descriptor for the input  +  /// getOrCreateFile - Get the file debug info descriptor for the input    /// location.    llvm::DIFile getOrCreateFile(SourceLocation Loc); @@ -308,43 +325,43 @@ private:    /// getOrCreateType - Get the type from the cache or create a new type if    /// necessary. -  llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile F); +  llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile Fg);    /// getOrCreateLimitedType - Get the type from the cache or create a new    /// partial type if necessary. -  llvm::DIType getOrCreateLimitedType(QualType Ty, llvm::DIFile F); +  llvm::DIType getOrCreateLimitedType(const RecordType *Ty, llvm::DIFile F);    /// CreateTypeNode - Create type metadata for a source language type. -  llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F); +  llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile Fg);    /// getObjCInterfaceDecl - return the underlying ObjCInterfaceDecl    /// if Ty is an ObjCInterface or a pointer to one.    ObjCInterfaceDecl* getObjCInterfaceDecl(QualType Ty); -  /// CreateLimitedTypeNode - Create type metadata for a source language -  /// type, but only partial types for records. -  llvm::DIType CreateLimitedTypeNode(QualType Ty, llvm::DIFile F); -    /// CreateMemberType - Create new member and increase Offset by FType's size.    llvm::DIType CreateMemberType(llvm::DIFile Unit, QualType FType,                                  StringRef Name, uint64_t *Offset); +  /// \brief Retrieve the DIDescriptor, if any, for the canonical form of this +  /// declaration. +  llvm::DIDescriptor getDeclarationOrDefinition(const Decl *D); +    /// getFunctionDeclaration - Return debug info descriptor to describe method    /// declaration for the given method definition.    llvm::DISubprogram getFunctionDeclaration(const Decl *D); -  /// getStaticDataMemberDeclaration - Return debug info descriptor to -  /// describe in-class static data member declaration for the given -  /// out-of-class definition. -  llvm::DIDerivedType getStaticDataMemberDeclaration(const Decl *D); +  /// Return debug info descriptor to describe in-class static data member +  /// declaration for the given out-of-class definition. +  llvm::DIDerivedType +  getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D);    /// getFunctionName - Get function name for the given FunctionDecl. If the -  /// name is constructred on demand (e.g. C++ destructor) then the name +  /// name is constructed on demand (e.g. C++ destructor) then the name    /// is stored on the side.    StringRef getFunctionName(const FunctionDecl *FD);    /// getObjCMethodName - Returns the unmangled name of an Objective-C method. -  /// This is the display name for the debugging info.   +  /// This is the display name for the debugging info.    StringRef getObjCMethodName(const ObjCMethodDecl *FD);    /// getSelectorName - Return selector name. This is used for debugging @@ -361,11 +378,62 @@ private:    /// then use current location.    unsigned getLineNumber(SourceLocation Loc); -  /// getColumnNumber - Get column number for the location. If location is  +  /// getColumnNumber - Get column number for the location. If location is    /// invalid then use current location.    /// \param Force  Assume DebugColumnInfo option is true.    unsigned getColumnNumber(SourceLocation Loc, bool Force=false); + +  /// internString - Allocate a copy of \p A using the DebugInfoNames allocator +  /// and return a reference to it. If multiple arguments are given the strings +  /// are concatenated. +  StringRef internString(StringRef A, StringRef B = StringRef()) { +    char *Data = DebugInfoNames.Allocate<char>(A.size() + B.size()); +    std::memcpy(Data, A.data(), A.size()); +    std::memcpy(Data + A.size(), B.data(), B.size()); +    return StringRef(Data, A.size() + B.size()); +  }  }; + +/// NoLocation - An RAII object that temporarily disables debug +/// locations. This is useful for emitting instructions that should be +/// counted towards the function prologue. +class NoLocation { +  SourceLocation SavedLoc; +  CGDebugInfo *DI; +  CGBuilderTy &Builder; +public: +  NoLocation(CodeGenFunction &CGF, CGBuilderTy &B); +  /// ~NoLocation - Autorestore everything back to normal. +  ~NoLocation(); +}; + +/// ArtificialLocation - An RAII object that temporarily switches to +/// an artificial debug location that has a valid scope, but no line +/// information. This is useful when emitting compiler-generated +/// helper functions that have no source location associated with +/// them. The DWARF specification allows the compiler to use the +/// special line number 0 to indicate code that can not be attributed +/// to any source location. +/// +/// This is necessary because passing an empty SourceLocation to +/// CGDebugInfo::setLocation() will result in the last valid location +/// being reused. +class ArtificialLocation { +  SourceLocation SavedLoc; +  CGDebugInfo *DI; +  CGBuilderTy &Builder; +public: +  ArtificialLocation(CodeGenFunction &CGF, CGBuilderTy &B); + +  /// Set the current location to line 0, but within the current scope +  /// (= the top of the LexicalBlockStack). +  void Emit(); + +  /// ~ArtificialLocation - Autorestore everything back to normal. +  ~ArtificialLocation(); +}; + +  } // namespace CodeGen  } // namespace clang diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 3ce6dec6a53c0..66d6b33eb6f00 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -21,6 +21,7 @@  #include "clang/AST/DeclObjC.h"  #include "clang/Basic/SourceManager.h"  #include "clang/Basic/TargetInfo.h" +#include "clang/CodeGen/CGFunctionInfo.h"  #include "clang/Frontend/CodeGenOptions.h"  #include "llvm/IR/DataLayout.h"  #include "llvm/IR/GlobalVariable.h" @@ -37,6 +38,8 @@ void CodeGenFunction::EmitDecl(const Decl &D) {    case Decl::UnresolvedUsingTypename:    case Decl::ClassTemplateSpecialization:    case Decl::ClassTemplatePartialSpecialization: +  case Decl::VarTemplateSpecialization: +  case Decl::VarTemplatePartialSpecialization:    case Decl::TemplateTypeParm:    case Decl::UnresolvedUsingValue:    case Decl::NonTypeTemplateParm: @@ -52,6 +55,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) {    case Decl::ParmVar:    case Decl::ImplicitParam:    case Decl::ClassTemplate: +  case Decl::VarTemplate:    case Decl::FunctionTemplate:    case Decl::TypeAliasTemplate:    case Decl::TemplateTemplateParm: @@ -72,15 +76,13 @@ void CodeGenFunction::EmitDecl(const Decl &D) {    case Decl::Block:    case Decl::Captured:    case Decl::ClassScopeFunctionSpecialization: +  case Decl::UsingShadow:      llvm_unreachable("Declaration should not be in declstmts!");    case Decl::Function:  // void X();    case Decl::Record:    // struct/union/class X;    case Decl::Enum:      // enum X;    case Decl::EnumConstant: // enum ? { X = ? }    case Decl::CXXRecord: // struct/union/class X; [C++] -  case Decl::Using:          // using X; [C++] -  case Decl::UsingShadow: -  case Decl::NamespaceAlias:    case Decl::StaticAssert: // static_assert(X, ""); [C++0x]    case Decl::Label:        // __label__ x;    case Decl::Import: @@ -89,6 +91,14 @@ void CodeGenFunction::EmitDecl(const Decl &D) {      // None of these decls require codegen support.      return; +  case Decl::NamespaceAlias: +    if (CGDebugInfo *DI = getDebugInfo()) +        DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(D)); +    return; +  case Decl::Using:          // using X; [C++] +    if (CGDebugInfo *DI = getDebugInfo()) +        DI->EmitUsingDecl(cast<UsingDecl>(D)); +    return;    case Decl::UsingDirective: // using namespace X; [C++]      if (CGDebugInfo *DI = getDebugInfo())        DI->EmitUsingDirective(cast<UsingDirectiveDecl>(D)); @@ -114,35 +124,32 @@ void CodeGenFunction::EmitDecl(const Decl &D) {  /// EmitVarDecl - This method handles emission of any variable declaration  /// inside a function, including static vars etc.  void CodeGenFunction::EmitVarDecl(const VarDecl &D) { -  switch (D.getStorageClass()) { -  case SC_None: -  case SC_Auto: -  case SC_Register: -    return EmitAutoVarDecl(D); -  case SC_Static: { +  if (D.isStaticLocal()) {      llvm::GlobalValue::LinkageTypes Linkage =        llvm::GlobalValue::InternalLinkage; -    // If the function definition has some sort of weak linkage, its -    // static variables should also be weak so that they get properly -    // uniqued.  We can't do this in C, though, because there's no -    // standard way to agree on which variables are the same (i.e. -    // there's no mangling). -    if (getLangOpts().CPlusPlus) -      if (llvm::GlobalValue::isWeakForLinker(CurFn->getLinkage())) -        Linkage = CurFn->getLinkage(); +    // If the variable is externally visible, it must have weak linkage so it +    // can be uniqued. +    if (D.isExternallyVisible()) { +      Linkage = llvm::GlobalValue::LinkOnceODRLinkage; + +      // FIXME: We need to force the emission/use of a guard variable for +      // some variables even if we can constant-evaluate them because +      // we can't guarantee every translation unit will constant-evaluate them. +    }      return EmitStaticVarDecl(D, Linkage);    } -  case SC_Extern: -  case SC_PrivateExtern: + +  if (D.hasExternalStorage())      // Don't emit it now, allow it to be emitted lazily on its first use.      return; -  case SC_OpenCLWorkGroupLocal: + +  if (D.getStorageClass() == SC_OpenCLWorkGroupLocal)      return CGM.getOpenCLRuntime().EmitWorkGroupLocalVarDecl(*this, D); -  } -  llvm_unreachable("Unknown storage class"); +  assert(D.hasLocalStorage()); +  return EmitAutoVarDecl(D);  }  static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D, @@ -200,8 +207,7 @@ CodeGenFunction::CreateStaticVarDecl(const VarDecl &D,                               llvm::GlobalVariable::NotThreadLocal,                               AddrSpace);    GV->setAlignment(getContext().getDeclAlign(&D).getQuantity()); -  if (Linkage != llvm::GlobalValue::InternalLinkage) -    GV->setVisibility(CurFn->getVisibility()); +  CGM.setGlobalVisibility(GV, &D);    if (D.getTLSKind())      CGM.setTLSMode(GV, D); @@ -420,7 +426,8 @@ namespace {        // byref or something.        DeclRefExpr DRE(const_cast<VarDecl*>(&Var), false,                        Var.getType(), VK_LValue, SourceLocation()); -      llvm::Value *value = CGF.EmitLoadOfScalar(CGF.EmitDeclRefLValue(&DRE)); +      llvm::Value *value = CGF.EmitLoadOfScalar(CGF.EmitDeclRefLValue(&DRE), +                                                SourceLocation());        CGF.EmitExtendGCLifetime(value);      }    }; @@ -647,7 +654,7 @@ void CodeGenFunction::EmitScalarInit(const Expr *init,    // might have to initialize with a barrier.  We have to do this for    // both __weak and __strong, but __weak got filtered out above.    if (accessedByInit && lifetime == Qualifiers::OCL_Strong) { -    llvm::Value *oldValue = EmitLoadOfScalar(lvalue); +    llvm::Value *oldValue = EmitLoadOfScalar(lvalue, init->getExprLoc());      EmitStoreOfScalar(value, lvalue, /* isInitialization */ true);      EmitARCRelease(oldValue, ARCImpreciseLifetime);      return; @@ -838,19 +845,19 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {      bool NRVO = getLangOpts().ElideConstructors &&        D.isNRVOVariable(); -    // If this value is a POD array or struct with a statically -    // determinable constant initializer, there are optimizations we can do. +    // If this value is an array or struct with a statically determinable +    // constant initializer, there are optimizations we can do.      //      // TODO: We should constant-evaluate the initializer of any variable,      // as long as it is initialized by a constant expression. Currently,      // isConstantInitializer produces wrong answers for structs with      // reference or bitfield members, and a few other cases, and checking      // for POD-ness protects us from some of these. -    if (D.getInit() && -        (Ty->isArrayType() || Ty->isRecordType()) && -        (Ty.isPODType(getContext()) || -         getContext().getBaseElementType(Ty)->isObjCObjectPointerType()) && -        D.getInit()->isConstantInitializer(getContext(), false)) { +    if (D.getInit() && (Ty->isArrayType() || Ty->isRecordType()) && +        (D.isConstexpr() || +         ((Ty.isPODType(getContext()) || +           getContext().getBaseElementType(Ty)->isObjCObjectPointerType()) && +          D.getInit()->isConstantInitializer(getContext(), false)))) {        // If the variable's a const type, and it's neither an NRVO        // candidate nor a __block variable and has no mutable members, @@ -1078,7 +1085,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {      capturedByInit ? emission.Address : emission.getObjectAddress(*this);    llvm::Constant *constant = 0; -  if (emission.IsConstantAggregate) { +  if (emission.IsConstantAggregate || D.isConstexpr()) {      assert(!capturedByInit && "constant init contains a capturing block?");      constant = CGM.EmitConstantInit(D, this);    } @@ -1089,6 +1096,13 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {      return EmitExprAsInit(Init, &D, lv, capturedByInit);    } +  if (!emission.IsConstantAggregate) { +    // For simple scalar/complex initialization, store the value directly. +    LValue lv = MakeAddrLValue(Loc, type, alignment); +    lv.setNonGC(true); +    return EmitStoreThroughLValue(RValue::get(constant), lv, true); +  } +    // If this is a simple aggregate initialization, we can optimize it    // in various ways.    bool isVolatile = type.isVolatileQualified(); @@ -1151,7 +1165,7 @@ void CodeGenFunction::EmitExprAsInit(const Expr *init,    QualType type = D->getType();    if (type->isReferenceType()) { -    RValue rvalue = EmitReferenceBindingToExpr(init, D); +    RValue rvalue = EmitReferenceBindingToExpr(init);      if (capturedByInit)        drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));      EmitStoreThroughLValue(rvalue, lvalue, true); @@ -1178,7 +1192,6 @@ void CodeGenFunction::EmitExprAsInit(const Expr *init,                                           AggValueSlot::DoesNotNeedGCBarriers,                                                AggValueSlot::IsNotAliased));      } -    MaybeEmitStdInitializerListCleanup(lvalue.getAddress(), init);      return;    }    llvm_unreachable("bad evaluation kind"); @@ -1331,6 +1344,26 @@ void CodeGenFunction::pushDestroy(CleanupKind cleanupKind, llvm::Value *addr,                                       destroyer, useEHCleanupForArray);  } +void CodeGenFunction::pushLifetimeExtendedDestroy( +    CleanupKind cleanupKind, llvm::Value *addr, QualType type, +    Destroyer *destroyer, bool useEHCleanupForArray) { +  assert(!isInConditionalBranch() && +         "performing lifetime extension from within conditional"); + +  // Push an EH-only cleanup for the object now. +  // FIXME: When popping normal cleanups, we need to keep this EH cleanup +  // around in case a temporary's destructor throws an exception. +  if (cleanupKind & EHCleanup) +    EHStack.pushCleanup<DestroyObject>( +        static_cast<CleanupKind>(cleanupKind & ~NormalCleanup), addr, type, +        destroyer, useEHCleanupForArray); + +  // Remember that we need to push a full cleanup for the object at the +  // end of the full-expression. +  pushCleanupAfterFullExpr<DestroyObject>( +      cleanupKind, addr, type, destroyer, useEHCleanupForArray); +} +  /// emitDestroy - Immediately perform the destruction of the given  /// object.  /// @@ -1608,10 +1641,18 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg,    }    llvm::Value *DeclPtr; +  bool HasNonScalarEvalKind = !CodeGenFunction::hasScalarEvaluationKind(Ty);    // If this is an aggregate or variable sized value, reuse the input pointer. -  if (!Ty->isConstantSizeType() || -      !CodeGenFunction::hasScalarEvaluationKind(Ty)) { +  if (HasNonScalarEvalKind || !Ty->isConstantSizeType()) {      DeclPtr = Arg; +    // Push a destructor cleanup for this parameter if the ABI requires it. +    if (HasNonScalarEvalKind && +        getTarget().getCXXABI().isArgumentDestroyedByCallee()) { +      if (const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl()) { +        if (RD->hasNonTrivialDestructor()) +          pushDestroy(QualType::DK_cxx_destructor, DeclPtr, Ty); +      } +    }    } else {      // Otherwise, create a temporary to hold the value.      llvm::AllocaInst *Alloc = CreateTempAlloca(ConvertTypeForMem(Ty), @@ -1649,7 +1690,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg,              // use objc_storeStrong(&dest, value) for retaining the              // object. But first, store a null into 'dest' because              // objc_storeStrong attempts to release its old value. -            llvm::Value * Null = CGM.EmitNullConstant(D.getType()); +            llvm::Value *Null = CGM.EmitNullConstant(D.getType());              EmitStoreOfScalar(Null, lv, /* isInitialization */ true);              EmitARCStoreStrongCall(lv.getAddress(), Arg, true);              doStore = false; diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp index 9ffcff2766230..7bdb9eb0a4a69 100644 --- a/lib/CodeGen/CGDeclCXX.cpp +++ b/lib/CodeGen/CGDeclCXX.cpp @@ -96,13 +96,14 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,      CXXDestructorDecl *dtor = record->getDestructor();      function = CGM.GetAddrOfCXXDestructor(dtor, Dtor_Complete); -    argument = addr; +    argument = llvm::ConstantExpr::getBitCast( +        addr, CGF.getTypes().ConvertType(type)->getPointerTo());    // Otherwise, the standard logic requires a helper function.    } else { -    function = CodeGenFunction(CGM).generateDestroyHelper(addr, type, -                                                  CGF.getDestroyer(dtorKind), -                                                  CGF.needsEHCleanup(dtorKind)); +    function = CodeGenFunction(CGM) +        .generateDestroyHelper(addr, type, CGF.getDestroyer(dtorKind), +                               CGF.needsEHCleanup(dtorKind), &D);      argument = llvm::Constant::getNullValue(CGF.Int8PtrTy);    } @@ -149,7 +150,7 @@ void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,    assert(PerformInit && "cannot have constant initializer which needs "           "destruction for reference");    unsigned Alignment = getContext().getDeclAlign(&D).getQuantity(); -  RValue RV = EmitReferenceBindingToExpr(Init, &D); +  RValue RV = EmitReferenceBindingToExpr(Init);    EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T);  } @@ -161,23 +162,24 @@ CreateGlobalInitOrDestructFunction(CodeGenModule &CGM,  /// Create a stub function, suitable for being passed to atexit,  /// which passes the given address to the given destructor function. -static llvm::Constant *createAtExitStub(CodeGenModule &CGM, +static llvm::Constant *createAtExitStub(CodeGenModule &CGM, const VarDecl &VD,                                          llvm::Constant *dtor,                                          llvm::Constant *addr) {    // Get the destructor function type, void(*)(void).    llvm::FunctionType *ty = llvm::FunctionType::get(CGM.VoidTy, false); +  SmallString<256> FnName; +  { +    llvm::raw_svector_ostream Out(FnName); +    CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&VD, Out); +  }    llvm::Function *fn = -    CreateGlobalInitOrDestructFunction(CGM, ty, -                                       Twine("__dtor_", addr->getName())); +      CreateGlobalInitOrDestructFunction(CGM, ty, FnName.str());    CodeGenFunction CGF(CGM); -  // Initialize debug info if needed. -  CGF.maybeInitializeDebugInfo(); - -  CGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, fn, -                    CGM.getTypes().arrangeNullaryFunction(), -                    FunctionArgList(), SourceLocation()); +  CGF.StartFunction(&VD, CGM.getContext().VoidTy, fn, +                    CGM.getTypes().arrangeNullaryFunction(), FunctionArgList(), +                    SourceLocation());    llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr); @@ -192,10 +194,11 @@ static llvm::Constant *createAtExitStub(CodeGenModule &CGM,  }  /// Register a global destructor using the C atexit runtime function. -void CodeGenFunction::registerGlobalDtorWithAtExit(llvm::Constant *dtor, +void CodeGenFunction::registerGlobalDtorWithAtExit(const VarDecl &VD, +                                                   llvm::Constant *dtor,                                                     llvm::Constant *addr) {    // Create a function which calls the destructor. -  llvm::Constant *dtorStub = createAtExitStub(CGM, dtor, addr); +  llvm::Constant *dtorStub = createAtExitStub(CGM, VD, dtor, addr);    // extern "C" int atexit(void (*f)(void));    llvm::FunctionType *atexitTy = @@ -257,10 +260,15 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,                                              llvm::GlobalVariable *Addr,                                              bool PerformInit) {    llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); +  SmallString<256> FnName; +  { +    llvm::raw_svector_ostream Out(FnName); +    getCXXABI().getMangleContext().mangleDynamicInitializer(D, Out); +  }    // Create a variable initialization function.    llvm::Function *Fn = -    CreateGlobalInitOrDestructFunction(*this, FTy, "__cxx_global_var_init"); +      CreateGlobalInitOrDestructFunction(*this, FTy, FnName.str());    CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr,                                                            PerformInit); @@ -278,6 +286,20 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,      OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size());      PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));      DelayedCXXInitPosition.erase(D); +  } else if (D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization && +             D->getTemplateSpecializationKind() != TSK_Undeclared) { +    // C++ [basic.start.init]p2: +    //   Definitions of explicitly specialized class template static data +    //   members have ordered initialization. Other class template static data +    //   members (i.e., implicitly or explicitly instantiated specializations) +    //   have unordered initialization. +    // +    // As a consequence, we can put them into their own llvm.global_ctors entry. +    // This should allow GlobalOpt to fire more often, and allow us to implement +    // the Microsoft C++ ABI, which uses COMDAT elimination to avoid double +    // initializaiton. +    AddGlobalCtor(Fn); +    DelayedCXXInitPosition.erase(D);    } else {      llvm::DenseMap<const Decl *, unsigned>::iterator I =        DelayedCXXInitPosition.find(D); @@ -386,8 +408,8 @@ void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,                                                   llvm::GlobalVariable *Addr,                                                         bool PerformInit) {    // Check if we need to emit debug info for variable initializer. -  if (!D->hasAttr<NoDebugAttr>()) -    maybeInitializeDebugInfo(); +  if (D->hasAttr<NoDebugAttr>()) +    DebugInfo = NULL; // disable debug info indefinitely for this function    StartFunction(GlobalDecl(D), getContext().VoidTy, Fn,                  getTypes().arrangeNullaryFunction(), @@ -410,9 +432,6 @@ void  CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,                                             ArrayRef<llvm::Constant *> Decls,                                             llvm::GlobalVariable *Guard) { -  // Initialize debug info if needed. -  maybeInitializeDebugInfo(); -    StartFunction(GlobalDecl(), getContext().VoidTy, Fn,                  getTypes().arrangeNullaryFunction(),                  FunctionArgList(), SourceLocation()); @@ -459,9 +478,6 @@ CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,  void CodeGenFunction::GenerateCXXGlobalDtorsFunc(llvm::Function *Fn,                    const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> >                                                  &DtorsAndObjects) { -  // Initialize debug info if needed. -  maybeInitializeDebugInfo(); -    StartFunction(GlobalDecl(), getContext().VoidTy, Fn,                  getTypes().arrangeNullaryFunction(),                  FunctionArgList(), SourceLocation()); @@ -481,11 +497,9 @@ void CodeGenFunction::GenerateCXXGlobalDtorsFunc(llvm::Function *Fn,  /// generateDestroyHelper - Generates a helper function which, when  /// invoked, destroys the given object. -llvm::Function *  -CodeGenFunction::generateDestroyHelper(llvm::Constant *addr, -                                       QualType type, -                                       Destroyer *destroyer, -                                       bool useEHCleanupForArray) { +llvm::Function *CodeGenFunction::generateDestroyHelper( +    llvm::Constant *addr, QualType type, Destroyer *destroyer, +    bool useEHCleanupForArray, const VarDecl *VD) {    FunctionArgList args;    ImplicitParamDecl dst(0, SourceLocation(), 0, getContext().VoidPtrTy);    args.push_back(&dst); @@ -498,11 +512,7 @@ CodeGenFunction::generateDestroyHelper(llvm::Constant *addr,    llvm::Function *fn =       CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor"); -  // Initialize debug info if needed. -  maybeInitializeDebugInfo(); - -  StartFunction(GlobalDecl(), getContext().VoidTy, fn, FI, args, -                SourceLocation()); +  StartFunction(VD, getContext().VoidTy, fn, FI, args, SourceLocation());    emitDestroy(addr, type, destroyer, useEHCleanupForArray); diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index a088d78641fa7..39a992aab17dc 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -89,7 +89,7 @@ static llvm::Constant *getEndCatchFn(CodeGenModule &CGM) {  }  static llvm::Constant *getUnexpectedFn(CodeGenModule &CGM) { -  // void __cxa_call_unexepcted(void *thrown_exception); +  // void __cxa_call_unexpected(void *thrown_exception);    llvm::FunctionType *FTy =      llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false); @@ -766,6 +766,11 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {    // Save the current IR generation state.    CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP(); +  SourceLocation SavedLocation; +  if (CGDebugInfo *DI = getDebugInfo()) { +    SavedLocation = DI->getLocation(); +    DI->EmitLocation(Builder, CurEHLocation); +  }    const EHPersonality &personality = EHPersonality::get(getLangOpts()); @@ -887,6 +892,8 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {    // Restore the old IR generation state.    Builder.restoreIP(savedIP); +  if (CGDebugInfo *DI = getDebugInfo()) +    DI->EmitLocation(Builder, SavedLocation);    return lpad;  } @@ -938,7 +945,8 @@ static llvm::Value *CallBeginCatch(CodeGenFunction &CGF,  /// parameter during catch initialization.  static void InitCatchParam(CodeGenFunction &CGF,                             const VarDecl &CatchParam, -                           llvm::Value *ParamAddr) { +                           llvm::Value *ParamAddr, +                           SourceLocation Loc) {    // Load the exception from where the landing pad saved it.    llvm::Value *Exn = CGF.getExceptionFromSlot(); @@ -1045,11 +1053,11 @@ static void InitCatchParam(CodeGenFunction &CGF,                                    CGF.getContext().getDeclAlign(&CatchParam));      switch (TEK) {      case TEK_Complex: -      CGF.EmitStoreOfComplex(CGF.EmitLoadOfComplex(srcLV), destLV, +      CGF.EmitStoreOfComplex(CGF.EmitLoadOfComplex(srcLV, Loc), destLV,                               /*init*/ true);        return;      case TEK_Scalar: { -      llvm::Value *ExnLoad = CGF.EmitLoadOfScalar(srcLV); +      llvm::Value *ExnLoad = CGF.EmitLoadOfScalar(srcLV, Loc);        CGF.EmitStoreOfScalar(ExnLoad, destLV, /*init*/ true);        return;      } @@ -1143,7 +1151,7 @@ static void BeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *S) {    // Emit the local.    CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(*CatchParam); -  InitCatchParam(CGF, *CatchParam, var.getObjectAddress(CGF)); +  InitCatchParam(CGF, *CatchParam, var.getObjectAddress(CGF), S->getLocStart());    CGF.EmitAutoVarCleanups(var);  } @@ -1612,8 +1620,15 @@ llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {    // end of the function by FinishFunction.    TerminateHandler = createBasicBlock("terminate.handler");    Builder.SetInsertPoint(TerminateHandler); -  llvm::CallInst *TerminateCall = EmitNounwindRuntimeCall(getTerminateFn(CGM)); -  TerminateCall->setDoesNotReturn(); +  llvm::CallInst *terminateCall; +  if (useClangCallTerminate(CGM)) { +    // Load the exception pointer. +    llvm::Value *exn = getExceptionFromSlot(); +    terminateCall = EmitNounwindRuntimeCall(getClangCallTerminateFn(CGM), exn); +  } else { +    terminateCall = EmitNounwindRuntimeCall(getTerminateFn(CGM)); +  } +  terminateCall->setDoesNotReturn();    Builder.CreateUnreachable();    // Restore the saved insertion state. @@ -1683,3 +1698,7 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {    return EHResumeBlock;  } + +void CodeGenFunction::EmitSEHTryStmt(const SEHTryStmt &S) { +  CGM.ErrorUnsupported(&S, "SEH __try"); +} diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 64670c5e81e45..cb990b243fba8 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -171,244 +171,240 @@ void CodeGenFunction::EmitAnyExprToMem(const Expr *E,    llvm_unreachable("bad evaluation kind");  } -static llvm::Value * -CreateReferenceTemporary(CodeGenFunction &CGF, QualType Type, -                         const NamedDecl *InitializedDecl) { -  if (const VarDecl *VD = dyn_cast_or_null<VarDecl>(InitializedDecl)) { -    if (VD->hasGlobalStorage()) { -      SmallString<256> Name; -      llvm::raw_svector_ostream Out(Name); -      CGF.CGM.getCXXABI().getMangleContext().mangleReferenceTemporary(VD, Out); -      Out.flush(); - -      llvm::Type *RefTempTy = CGF.ConvertTypeForMem(Type); -   -      // Create the reference temporary. -      llvm::GlobalVariable *RefTemp = -        new llvm::GlobalVariable(CGF.CGM.getModule(),  -                                 RefTempTy, /*isConstant=*/false, -                                 llvm::GlobalValue::InternalLinkage, -                                 llvm::Constant::getNullValue(RefTempTy), -                                 Name.str()); -      // If we're binding to a thread_local variable, the temporary is also -      // thread local. -      if (VD->getTLSKind()) -        CGF.CGM.setTLSMode(RefTemp, *VD); -      return RefTemp; -    } -  } - -  return CGF.CreateMemTemp(Type, "ref.tmp"); -} - -static llvm::Value * -EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E, -                            llvm::Value *&ReferenceTemporary, -                            const CXXDestructorDecl *&ReferenceTemporaryDtor, -                            const InitListExpr *&ReferenceInitializerList, -                            QualType &ObjCARCReferenceLifetimeType, -                            const NamedDecl *InitializedDecl) { -  const MaterializeTemporaryExpr *M = NULL; -  E = E->findMaterializedTemporary(M); +static void +pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M, +                     const Expr *E, llvm::Value *ReferenceTemporary) {    // Objective-C++ ARC:    //   If we are binding a reference to a temporary that has ownership, we    //   need to perform retain/release operations on the temporary. -  if (M && CGF.getLangOpts().ObjCAutoRefCount && -      M->getType()->isObjCLifetimeType() && -      (M->getType().getObjCLifetime() == Qualifiers::OCL_Strong || -       M->getType().getObjCLifetime() == Qualifiers::OCL_Weak || -       M->getType().getObjCLifetime() == Qualifiers::OCL_Autoreleasing)) -    ObjCARCReferenceLifetimeType = M->getType(); - -  if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(E)) { -    CGF.enterFullExpression(EWC); -    CodeGenFunction::RunCleanupsScope Scope(CGF); - -    return EmitExprForReferenceBinding(CGF, EWC->getSubExpr(),  -                                       ReferenceTemporary,  -                                       ReferenceTemporaryDtor, -                                       ReferenceInitializerList, -                                       ObjCARCReferenceLifetimeType, -                                       InitializedDecl); -  } - -  if (E->isGLValue()) { -    // Emit the expression as an lvalue. -    LValue LV = CGF.EmitLValue(E); -    assert(LV.isSimple()); -    return LV.getAddress(); -  } -   -  if (!ObjCARCReferenceLifetimeType.isNull()) { -    ReferenceTemporary = CreateReferenceTemporary(CGF,  -                                                ObjCARCReferenceLifetimeType,  -                                                  InitializedDecl); -     -     -    LValue RefTempDst = CGF.MakeAddrLValue(ReferenceTemporary,  -                                           ObjCARCReferenceLifetimeType); - -    CGF.EmitScalarInit(E, dyn_cast_or_null<ValueDecl>(InitializedDecl), -                       RefTempDst, false); -     -    bool ExtendsLifeOfTemporary = false; -    if (const VarDecl *Var = dyn_cast_or_null<VarDecl>(InitializedDecl)) { -      if (Var->extendsLifetimeOfTemporary()) -        ExtendsLifeOfTemporary = true; -    } else if (InitializedDecl && isa<FieldDecl>(InitializedDecl)) { -      ExtendsLifeOfTemporary = true; -    } -     -    if (!ExtendsLifeOfTemporary) { -      // Since the lifetime of this temporary isn't going to be extended, -      // we need to clean it up ourselves at the end of the full expression. -      switch (ObjCARCReferenceLifetimeType.getObjCLifetime()) { -      case Qualifiers::OCL_None: -      case Qualifiers::OCL_ExplicitNone: -      case Qualifiers::OCL_Autoreleasing: -        break; -           -      case Qualifiers::OCL_Strong: { -        assert(!ObjCARCReferenceLifetimeType->isArrayType()); -        CleanupKind cleanupKind = CGF.getARCCleanupKind(); -        CGF.pushDestroy(cleanupKind,  -                        ReferenceTemporary, -                        ObjCARCReferenceLifetimeType, -                        CodeGenFunction::destroyARCStrongImprecise, -                        cleanupKind & EHCleanup); -        break; -      } -         -      case Qualifiers::OCL_Weak: +  // +  // FIXME: This should be looking at E, not M. +  if (CGF.getLangOpts().ObjCAutoRefCount && +      M->getType()->isObjCLifetimeType()) { +    QualType ObjCARCReferenceLifetimeType = M->getType(); +    switch (Qualifiers::ObjCLifetime Lifetime = +                ObjCARCReferenceLifetimeType.getObjCLifetime()) { +    case Qualifiers::OCL_None: +    case Qualifiers::OCL_ExplicitNone: +      // Carry on to normal cleanup handling. +      break; + +    case Qualifiers::OCL_Autoreleasing: +      // Nothing to do; cleaned up by an autorelease pool. +      return; + +    case Qualifiers::OCL_Strong: +    case Qualifiers::OCL_Weak: +      switch (StorageDuration Duration = M->getStorageDuration()) { +      case SD_Static: +        // Note: we intentionally do not register a cleanup to release +        // the object on program termination. +        return; + +      case SD_Thread: +        // FIXME: We should probably register a cleanup in this case. +        return; + +      case SD_Automatic: +      case SD_FullExpression:          assert(!ObjCARCReferenceLifetimeType->isArrayType()); -        CGF.pushDestroy(NormalAndEHCleanup,  -                        ReferenceTemporary, -                        ObjCARCReferenceLifetimeType, -                        CodeGenFunction::destroyARCWeak, -                        /*useEHCleanupForArray*/ true); -        break; +        CodeGenFunction::Destroyer *Destroy; +        CleanupKind CleanupKind; +        if (Lifetime == Qualifiers::OCL_Strong) { +          const ValueDecl *VD = M->getExtendingDecl(); +          bool Precise = +              VD && isa<VarDecl>(VD) && VD->hasAttr<ObjCPreciseLifetimeAttr>(); +          CleanupKind = CGF.getARCCleanupKind(); +          Destroy = Precise ? &CodeGenFunction::destroyARCStrongPrecise +                            : &CodeGenFunction::destroyARCStrongImprecise; +        } else { +          // __weak objects always get EH cleanups; otherwise, exceptions +          // could cause really nasty crashes instead of mere leaks. +          CleanupKind = NormalAndEHCleanup; +          Destroy = &CodeGenFunction::destroyARCWeak; +        } +        if (Duration == SD_FullExpression) +          CGF.pushDestroy(CleanupKind, ReferenceTemporary, +                          ObjCARCReferenceLifetimeType, *Destroy, +                          CleanupKind & EHCleanup); +        else +          CGF.pushLifetimeExtendedDestroy(CleanupKind, ReferenceTemporary, +                                          ObjCARCReferenceLifetimeType, +                                          *Destroy, CleanupKind & EHCleanup); +        return; + +      case SD_Dynamic: +        llvm_unreachable("temporary cannot have dynamic storage duration");        } -       -      ObjCARCReferenceLifetimeType = QualType(); +      llvm_unreachable("unknown storage duration");      } -     -    return ReferenceTemporary;    } -  SmallVector<SubobjectAdjustment, 2> Adjustments; -  E = E->skipRValueSubobjectAdjustments(Adjustments); -  if (const OpaqueValueExpr *opaque = dyn_cast<OpaqueValueExpr>(E)) -    if (opaque->getType()->isRecordType()) -      return CGF.EmitOpaqueValueLValue(opaque).getAddress(); +  CXXDestructorDecl *ReferenceTemporaryDtor = 0; +  if (const RecordType *RT = +          E->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()) { +    // Get the destructor for the reference temporary. +    CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(RT->getDecl()); +    if (!ClassDecl->hasTrivialDestructor()) +      ReferenceTemporaryDtor = ClassDecl->getDestructor(); +  } -  // Create a reference temporary if necessary. -  AggValueSlot AggSlot = AggValueSlot::ignored(); -  if (CGF.hasAggregateEvaluationKind(E->getType())) { -    ReferenceTemporary = CreateReferenceTemporary(CGF, E->getType(),  -                                                  InitializedDecl); -    CharUnits Alignment = CGF.getContext().getTypeAlignInChars(E->getType()); -    AggValueSlot::IsDestructed_t isDestructed -      = AggValueSlot::IsDestructed_t(InitializedDecl != 0); -    AggSlot = AggValueSlot::forAddr(ReferenceTemporary, Alignment, -                                    Qualifiers(), isDestructed, -                                    AggValueSlot::DoesNotNeedGCBarriers, -                                    AggValueSlot::IsNotAliased); -  } -   -  if (InitializedDecl) { -    if (const InitListExpr *ILE = dyn_cast<InitListExpr>(E)) { -      if (ILE->initializesStdInitializerList()) { -        ReferenceInitializerList = ILE; -      } -    } -    else if (const RecordType *RT = -               E->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()){ -      // Get the destructor for the reference temporary. -      CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(RT->getDecl()); -      if (!ClassDecl->hasTrivialDestructor()) -        ReferenceTemporaryDtor = ClassDecl->getDestructor(); +  if (!ReferenceTemporaryDtor) +    return; + +  // Call the destructor for the temporary. +  switch (M->getStorageDuration()) { +  case SD_Static: +  case SD_Thread: { +    llvm::Constant *CleanupFn; +    llvm::Constant *CleanupArg; +    if (E->getType()->isArrayType()) { +      CleanupFn = CodeGenFunction(CGF.CGM).generateDestroyHelper( +          cast<llvm::Constant>(ReferenceTemporary), E->getType(), +          CodeGenFunction::destroyCXXObject, CGF.getLangOpts().Exceptions, +          dyn_cast_or_null<VarDecl>(M->getExtendingDecl())); +      CleanupArg = llvm::Constant::getNullValue(CGF.Int8PtrTy); +    } else { +      CleanupFn = +        CGF.CGM.GetAddrOfCXXDestructor(ReferenceTemporaryDtor, Dtor_Complete); +      CleanupArg = cast<llvm::Constant>(ReferenceTemporary);      } +    CGF.CGM.getCXXABI().registerGlobalDtor( +        CGF, *cast<VarDecl>(M->getExtendingDecl()), CleanupFn, CleanupArg); +    break;    } -  RValue RV = CGF.EmitAnyExpr(E, AggSlot); - -  // Check if need to perform derived-to-base casts and/or field accesses, to -  // get from the temporary object we created (and, potentially, for which we -  // extended the lifetime) to the subobject we're binding the reference to. -  if (!Adjustments.empty()) { -    llvm::Value *Object = RV.getAggregateAddr(); -    for (unsigned I = Adjustments.size(); I != 0; --I) { -      SubobjectAdjustment &Adjustment = Adjustments[I-1]; -      switch (Adjustment.Kind) { -      case SubobjectAdjustment::DerivedToBaseAdjustment: -        Object =  -            CGF.GetAddressOfBaseClass(Object,  -                                      Adjustment.DerivedToBase.DerivedClass,  -                            Adjustment.DerivedToBase.BasePath->path_begin(), -                            Adjustment.DerivedToBase.BasePath->path_end(), -                                      /*NullCheckValue=*/false); -        break; -           -      case SubobjectAdjustment::FieldAdjustment: { -        LValue LV = CGF.MakeAddrLValue(Object, E->getType()); -        LV = CGF.EmitLValueForField(LV, Adjustment.Field); -        if (LV.isSimple()) { -          Object = LV.getAddress(); -          break; -        } -         -        // For non-simple lvalues, we actually have to create a copy of -        // the object we're binding to. -        QualType T = Adjustment.Field->getType().getNonReferenceType() -                                                .getUnqualifiedType(); -        Object = CreateReferenceTemporary(CGF, T, InitializedDecl); -        LValue TempLV = CGF.MakeAddrLValue(Object, -                                           Adjustment.Field->getType()); -        CGF.EmitStoreThroughLValue(CGF.EmitLoadOfLValue(LV), TempLV); -        break; -      } +  case SD_FullExpression: +    CGF.pushDestroy(NormalAndEHCleanup, ReferenceTemporary, E->getType(), +                    CodeGenFunction::destroyCXXObject, +                    CGF.getLangOpts().Exceptions); +    break; -      case SubobjectAdjustment::MemberPointerAdjustment: { -        llvm::Value *Ptr = CGF.EmitScalarExpr(Adjustment.Ptr.RHS); -        Object = CGF.CGM.getCXXABI().EmitMemberDataPointerAddress( -                      CGF, Object, Ptr, Adjustment.Ptr.MPT); -        break; -      } -      } +  case SD_Automatic: +    CGF.pushLifetimeExtendedDestroy(NormalAndEHCleanup, +                                    ReferenceTemporary, E->getType(), +                                    CodeGenFunction::destroyCXXObject, +                                    CGF.getLangOpts().Exceptions); +    break; + +  case SD_Dynamic: +    llvm_unreachable("temporary cannot have dynamic storage duration"); +  } +} + +static llvm::Value * +createReferenceTemporary(CodeGenFunction &CGF, +                         const MaterializeTemporaryExpr *M, const Expr *Inner) { +  switch (M->getStorageDuration()) { +  case SD_FullExpression: +  case SD_Automatic: +    return CGF.CreateMemTemp(Inner->getType(), "ref.tmp"); + +  case SD_Thread: +  case SD_Static: +    return CGF.CGM.GetAddrOfGlobalTemporary(M, Inner); + +  case SD_Dynamic: +    llvm_unreachable("temporary can't have dynamic storage duration"); +  } +  llvm_unreachable("unknown storage duration"); +} + +LValue CodeGenFunction::EmitMaterializeTemporaryExpr( +                                           const MaterializeTemporaryExpr *M) { +  const Expr *E = M->GetTemporaryExpr(); + +  if (getLangOpts().ObjCAutoRefCount && +      M->getType()->isObjCLifetimeType() && +      M->getType().getObjCLifetime() != Qualifiers::OCL_None && +      M->getType().getObjCLifetime() != Qualifiers::OCL_ExplicitNone) { +    // FIXME: Fold this into the general case below. +    llvm::Value *Object = createReferenceTemporary(*this, M, E); +    LValue RefTempDst = MakeAddrLValue(Object, M->getType()); + +    if (llvm::GlobalVariable *Var = dyn_cast<llvm::GlobalVariable>(Object)) { +      // We should not have emitted the initializer for this temporary as a +      // constant. +      assert(!Var->hasInitializer()); +      Var->setInitializer(CGM.EmitNullConstant(E->getType()));      } -    return Object; +    EmitScalarInit(E, M->getExtendingDecl(), RefTempDst, false); + +    pushTemporaryCleanup(*this, M, E, Object); +    return RefTempDst;    } -  if (RV.isAggregate()) -    return RV.getAggregateAddr(); +  SmallVector<const Expr *, 2> CommaLHSs; +  SmallVector<SubobjectAdjustment, 2> Adjustments; +  E = E->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments); + +  for (unsigned I = 0, N = CommaLHSs.size(); I != N; ++I) +    EmitIgnoredExpr(CommaLHSs[I]); -  // Create a temporary variable that we can bind the reference to. -  ReferenceTemporary = CreateReferenceTemporary(CGF, E->getType(),  -                                                InitializedDecl); +  if (const OpaqueValueExpr *opaque = dyn_cast<OpaqueValueExpr>(E)) { +    if (opaque->getType()->isRecordType()) { +      assert(Adjustments.empty()); +      return EmitOpaqueValueLValue(opaque); +    } +  } +  // Create and initialize the reference temporary. +  llvm::Value *Object = createReferenceTemporary(*this, M, E); +  if (llvm::GlobalVariable *Var = dyn_cast<llvm::GlobalVariable>(Object)) { +    // If the temporary is a global and has a constant initializer, we may +    // have already initialized it. +    if (!Var->hasInitializer()) { +      Var->setInitializer(CGM.EmitNullConstant(E->getType())); +      EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/true); +    } +  } else { +    EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/true); +  } +  pushTemporaryCleanup(*this, M, E, Object); + +  // Perform derived-to-base casts and/or field accesses, to get from the +  // temporary object we created (and, potentially, for which we extended +  // the lifetime) to the subobject we're binding the reference to. +  for (unsigned I = Adjustments.size(); I != 0; --I) { +    SubobjectAdjustment &Adjustment = Adjustments[I-1]; +    switch (Adjustment.Kind) { +    case SubobjectAdjustment::DerivedToBaseAdjustment: +      Object = +          GetAddressOfBaseClass(Object, Adjustment.DerivedToBase.DerivedClass, +                                Adjustment.DerivedToBase.BasePath->path_begin(), +                                Adjustment.DerivedToBase.BasePath->path_end(), +                                /*NullCheckValue=*/ false); +      break; -  LValue tempLV = CGF.MakeNaturalAlignAddrLValue(ReferenceTemporary, -                                                 E->getType()); -  if (RV.isScalar()) -    CGF.EmitStoreOfScalar(RV.getScalarVal(), tempLV, /*init*/ true); -  else -    CGF.EmitStoreOfComplex(RV.getComplexVal(), tempLV, /*init*/ true); -  return ReferenceTemporary; +    case SubobjectAdjustment::FieldAdjustment: { +      LValue LV = MakeAddrLValue(Object, E->getType()); +      LV = EmitLValueForField(LV, Adjustment.Field); +      assert(LV.isSimple() && +             "materialized temporary field is not a simple lvalue"); +      Object = LV.getAddress(); +      break; +    } + +    case SubobjectAdjustment::MemberPointerAdjustment: { +      llvm::Value *Ptr = EmitScalarExpr(Adjustment.Ptr.RHS); +      Object = CGM.getCXXABI().EmitMemberDataPointerAddress( +                    *this, Object, Ptr, Adjustment.Ptr.MPT); +      break; +    } +    } +  } + +  return MakeAddrLValue(Object, M->getType());  }  RValue -CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E, -                                            const NamedDecl *InitializedDecl) { -  llvm::Value *ReferenceTemporary = 0; -  const CXXDestructorDecl *ReferenceTemporaryDtor = 0; -  const InitListExpr *ReferenceInitializerList = 0; -  QualType ObjCARCReferenceLifetimeType; -  llvm::Value *Value = EmitExprForReferenceBinding(*this, E, ReferenceTemporary, -                                                   ReferenceTemporaryDtor, -                                                   ReferenceInitializerList, -                                                   ObjCARCReferenceLifetimeType, -                                                   InitializedDecl); +CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E) { +  // Emit the expression as an lvalue. +  LValue LV = EmitLValue(E); +  assert(LV.isSimple()); +  llvm::Value *Value = LV.getAddress(); +    if (SanitizePerformTypeCheck && !E->getType()->isFunctionType()) {      // C++11 [dcl.ref]p5 (as amended by core issue 453):      //   If a glvalue to which a reference is directly bound designates neither @@ -418,80 +414,7 @@ CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E,      QualType Ty = E->getType();      EmitTypeCheck(TCK_ReferenceBinding, E->getExprLoc(), Value, Ty);    } -  if (!ReferenceTemporaryDtor && !ReferenceInitializerList && -      ObjCARCReferenceLifetimeType.isNull()) -    return RValue::get(Value); -   -  // Make sure to call the destructor for the reference temporary. -  const VarDecl *VD = dyn_cast_or_null<VarDecl>(InitializedDecl); -  if (VD && VD->hasGlobalStorage()) { -    if (ReferenceTemporaryDtor) { -      llvm::Constant *CleanupFn; -      llvm::Constant *CleanupArg; -      if (E->getType()->isArrayType()) { -        CleanupFn = CodeGenFunction(CGM).generateDestroyHelper( -            cast<llvm::Constant>(ReferenceTemporary), E->getType(), -            destroyCXXObject, getLangOpts().Exceptions); -        CleanupArg = llvm::Constant::getNullValue(Int8PtrTy); -      } else { -        CleanupFn = -          CGM.GetAddrOfCXXDestructor(ReferenceTemporaryDtor, Dtor_Complete); -        CleanupArg = cast<llvm::Constant>(ReferenceTemporary); -      } -      CGM.getCXXABI().registerGlobalDtor(*this, *VD, CleanupFn, CleanupArg); -    } else if (ReferenceInitializerList) { -      // FIXME: This is wrong. We need to register a global destructor to clean -      // up the initializer_list object, rather than adding it as a local -      // cleanup. -      EmitStdInitializerListCleanup(ReferenceTemporary, -                                    ReferenceInitializerList); -    } else { -      assert(!ObjCARCReferenceLifetimeType.isNull() && !VD->getTLSKind()); -      // Note: We intentionally do not register a global "destructor" to -      // release the object. -    } -     -    return RValue::get(Value); -  } -  if (ReferenceTemporaryDtor) { -    if (E->getType()->isArrayType()) -      pushDestroy(NormalAndEHCleanup, ReferenceTemporary, E->getType(), -                  destroyCXXObject, getLangOpts().Exceptions); -    else -      PushDestructorCleanup(ReferenceTemporaryDtor, ReferenceTemporary); -  } else if (ReferenceInitializerList) { -    EmitStdInitializerListCleanup(ReferenceTemporary, -                                  ReferenceInitializerList); -  } else { -    switch (ObjCARCReferenceLifetimeType.getObjCLifetime()) { -    case Qualifiers::OCL_None: -      llvm_unreachable( -                      "Not a reference temporary that needs to be deallocated"); -    case Qualifiers::OCL_ExplicitNone: -    case Qualifiers::OCL_Autoreleasing: -      // Nothing to do. -      break;         -         -    case Qualifiers::OCL_Strong: { -      bool precise = VD && VD->hasAttr<ObjCPreciseLifetimeAttr>(); -      CleanupKind cleanupKind = getARCCleanupKind(); -      pushDestroy(cleanupKind, ReferenceTemporary, ObjCARCReferenceLifetimeType, -                  precise ? destroyARCStrongPrecise : destroyARCStrongImprecise, -                  cleanupKind & EHCleanup); -      break; -    } -         -    case Qualifiers::OCL_Weak: { -      // __weak objects always get EH cleanups; otherwise, exceptions -      // could cause really nasty crashes instead of mere leaks. -      pushDestroy(NormalAndEHCleanup, ReferenceTemporary, -                  ObjCARCReferenceLifetimeType, destroyARCWeak, true); -      break;         -    } -    } -  } -      return RValue::get(Value);  } @@ -553,7 +476,9 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,      // The glvalue must refer to a large enough storage region.      // FIXME: If Address Sanitizer is enabled, insert dynamic instrumentation      //        to check this. -    llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, IntPtrTy); +    // FIXME: Get object address space +    llvm::Type *Tys[2] = { IntPtrTy, Int8PtrTy }; +    llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);      llvm::Value *Min = Builder.getFalse();      llvm::Value *CastAddr = Builder.CreateBitCast(Address, Int8PtrTy);      llvm::Value *LargeEnough = @@ -716,7 +641,8 @@ static llvm::Value *getArrayIndexingBound(  void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base,                                        llvm::Value *Index, QualType IndexType,                                        bool Accessed) { -  assert(SanOpts->Bounds && "should not be called unless adding bounds checks"); +  assert(SanOpts->ArrayBounds && +         "should not be called unless adding bounds checks");    QualType IndexedType;    llvm::Value *Bound = getArrayIndexingBound(*this, Base, IndexedType); @@ -741,13 +667,13 @@ void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base,  CodeGenFunction::ComplexPairTy CodeGenFunction::  EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,                           bool isInc, bool isPre) { -  ComplexPairTy InVal = EmitLoadOfComplex(LV); -   +  ComplexPairTy InVal = EmitLoadOfComplex(LV, E->getExprLoc()); +    llvm::Value *NextVal;    if (isa<llvm::IntegerType>(InVal.first->getType())) {      uint64_t AmountVal = isInc ? 1 : -1;      NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal, true); -     +      // Add the inc/dec to the real part.      NextVal = Builder.CreateAdd(InVal.first, NextVal, isInc ? "inc" : "dec");    } else { @@ -756,16 +682,16 @@ EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,      if (!isInc)        FVal.changeSign();      NextVal = llvm::ConstantFP::get(getLLVMContext(), FVal); -     +      // Add the inc/dec to the real part.      NextVal = Builder.CreateFAdd(InVal.first, NextVal, isInc ? "inc" : "dec");    } -   +    ComplexPairTy IncVal(NextVal, InVal.second); -   +    // Store the updated result through the lvalue.    EmitStoreOfComplex(IncVal, LV, /*init*/ false); -   +    // If this is a postinc, return the value read from memory, otherwise use the    // updated value.    return isPre ? IncVal : InVal; @@ -787,7 +713,7 @@ RValue CodeGenFunction::GetUndefRValue(QualType Ty) {      llvm::Value *U = llvm::UndefValue::get(EltTy);      return RValue::getComplex(std::make_pair(U, U));    } -   +    // If this is a use of an undefined aggregate type, the aggregate must have an    // identifiable address.  Just because the contents of the value are undefined    // doesn't mean that the address can't be taken and compared. @@ -817,7 +743,7 @@ LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,  LValue CodeGenFunction::EmitCheckedLValue(const Expr *E, TypeCheckKind TCK) {    LValue LV; -  if (SanOpts->Bounds && isa<ArraySubscriptExpr>(E)) +  if (SanOpts->ArrayBounds && isa<ArraySubscriptExpr>(E))      LV = EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E), /*Accessed*/true);    else      LV = EmitLValue(E); @@ -899,8 +825,6 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {      return EmitLValue(cleanups->getSubExpr());    } -  case Expr::CXXScalarValueInitExprClass: -    return EmitNullInitializationLValue(cast<CXXScalarValueInitExpr>(E));    case Expr::CXXDefaultArgExprClass:      return EmitLValue(cast<CXXDefaultArgExpr>(E)->getExpr());    case Expr::CXXDefaultInitExprClass: { @@ -931,7 +855,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {    case Expr::BinaryConditionalOperatorClass:      return EmitConditionalOperatorLValue(cast<BinaryConditionalOperator>(E));    case Expr::ChooseExprClass: -    return EmitLValue(cast<ChooseExpr>(E)->getChosenSubExpr(getContext())); +    return EmitLValue(cast<ChooseExpr>(E)->getChosenSubExpr());    case Expr::OpaqueValueExprClass:      return EmitOpaqueValueLValue(cast<OpaqueValueExpr>(E));    case Expr::SubstNonTypeTemplateParmExprClass: @@ -1047,7 +971,7 @@ CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {    llvm::Constant *C = CGM.EmitConstantValue(result.Val, resultType, this);    // Make sure we emit a debug reference to the global variable. -  // This should probably fire even for  +  // This should probably fire even for    if (isa<VarDecl>(value)) {      if (!getContext().DeclMustBeEmitted(cast<VarDecl>(value)))        EmitDeclRefExprDbgValue(refExpr, C); @@ -1063,10 +987,11 @@ CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {    return ConstantEmission::forValue(C);  } -llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue) { +llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue, +                                               SourceLocation Loc) {    return EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),                            lvalue.getAlignment().getQuantity(), -                          lvalue.getType(), lvalue.getTBAAInfo(), +                          lvalue.getType(), Loc, lvalue.getTBAAInfo(),                            lvalue.getTBAABaseType(), lvalue.getTBAAOffset());  } @@ -1128,21 +1053,22 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {  }  llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, -                                              unsigned Alignment, QualType Ty, -                                              llvm::MDNode *TBAAInfo, -                                              QualType TBAABaseType, -                                              uint64_t TBAAOffset) { +                                               unsigned Alignment, QualType Ty, +                                               SourceLocation Loc, +                                               llvm::MDNode *TBAAInfo, +                                               QualType TBAABaseType, +                                               uint64_t TBAAOffset) {    // For better performance, handle vector loads differently.    if (Ty->isVectorType()) {      llvm::Value *V;      const llvm::Type *EltTy =      cast<llvm::PointerType>(Addr->getType())->getElementType(); -     +      const llvm::VectorType *VTy = cast<llvm::VectorType>(EltTy); -       +      // Handle vectors of size 3, like size 4 for better performance.      if (VTy->getNumElements() == 3) { -         +        // Bitcast to vec4 type.        llvm::VectorType *vec4Ty = llvm::VectorType::get(VTy->getElementType(),                                                           4); @@ -1175,9 +1101,9 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,      LValue lvalue = LValue::MakeAddr(Addr, Ty,                                       CharUnits::fromQuantity(Alignment),                                       getContext(), TBAAInfo); -    return EmitAtomicLoad(lvalue).getScalarVal(); +    return EmitAtomicLoad(lvalue, Loc).getScalarVal();    } -   +    llvm::LoadInst *Load = Builder.CreateLoad(Addr);    if (Volatile)      Load->setVolatile(true); @@ -1186,7 +1112,8 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,    if (TBAAInfo) {      llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo,                                                        TBAAOffset); -    CGM.DecorateInstruction(Load, TBAAPath, false/*ConvertTypeToTag*/); +    if (TBAAPath) +      CGM.DecorateInstruction(Load, TBAAPath, false/*ConvertTypeToTag*/);    }    if ((SanOpts->Bool && hasBooleanRepresentation(Ty)) || @@ -1205,9 +1132,12 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,            Load, llvm::ConstantInt::get(getLLVMContext(), Min));          Check = Builder.CreateAnd(Upper, Lower);        } -      // FIXME: Provide a SourceLocation. -      EmitCheck(Check, "load_invalid_value", EmitCheckTypeDescriptor(Ty), -                EmitCheckValue(Load), CRK_Recoverable); +      llvm::Constant *StaticArgs[] = { +        EmitCheckSourceLocation(Loc), +        EmitCheckTypeDescriptor(Ty) +      }; +      EmitCheck(Check, "load_invalid_value", StaticArgs, EmitCheckValue(Load), +                CRK_Recoverable);      }    } else if (CGM.getCodeGenOpts().OptimizationLevel > 0)      if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty)) @@ -1243,11 +1173,10 @@ llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) {  void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,                                          bool Volatile, unsigned Alignment, -                                        QualType Ty, -                                        llvm::MDNode *TBAAInfo, +                                        QualType Ty, llvm::MDNode *TBAAInfo,                                          bool isInit, QualType TBAABaseType,                                          uint64_t TBAAOffset) { -   +    // Handle vectors differently to get better performance.    if (Ty->isVectorType()) {      llvm::Type *SrcTy = Value->getType(); @@ -1255,20 +1184,17 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,      // Handle vec3 special.      if (VecTy->getNumElements() == 3) {        llvm::LLVMContext &VMContext = getLLVMContext(); -       +        // Our source is a vec3, do a shuffle vector to make it a vec4.        SmallVector<llvm::Constant*, 4> Mask; -      Mask.push_back(llvm::ConstantInt::get( -                                            llvm::Type::getInt32Ty(VMContext), +      Mask.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),                                              0)); -      Mask.push_back(llvm::ConstantInt::get( -                                            llvm::Type::getInt32Ty(VMContext), +      Mask.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),                                              1)); -      Mask.push_back(llvm::ConstantInt::get( -                                            llvm::Type::getInt32Ty(VMContext), +      Mask.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),                                              2));        Mask.push_back(llvm::UndefValue::get(llvm::Type::getInt32Ty(VMContext))); -       +        llvm::Value *MaskV = llvm::ConstantVector::get(Mask);        Value = Builder.CreateShuffleVector(Value,                                            llvm::UndefValue::get(VecTy), @@ -1282,7 +1208,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,        Addr = Builder.CreateBitCast(Addr, MemTy, "storetmp");      }    } -   +    Value = EmitToMemory(Value, Ty);    if (Ty->isAtomicType()) { @@ -1300,7 +1226,8 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,    if (TBAAInfo) {      llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo,                                                        TBAAOffset); -    CGM.DecorateInstruction(Store, TBAAPath, false/*ConvertTypeToTag*/); +    if (TBAAPath) +      CGM.DecorateInstruction(Store, TBAAPath, false/*ConvertTypeToTag*/);    }  } @@ -1315,7 +1242,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue,  /// EmitLoadOfLValue - Given an expression that represents a value lvalue, this  /// method emits the address of the lvalue, then loads the result as an rvalue,  /// returning the rvalue. -RValue CodeGenFunction::EmitLoadOfLValue(LValue LV) { +RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, SourceLocation Loc) {    if (LV.isObjCWeak()) {      // load of a __weak object.      llvm::Value *AddrWeakObj = LV.getAddress(); @@ -1332,7 +1259,7 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV) {      assert(!LV.getType()->isFunctionType());      // Everything needs a load. -    return RValue::get(EmitLoadOfScalar(LV)); +    return RValue::get(EmitLoadOfScalar(LV, Loc));    }    if (LV.isVectorElt()) { @@ -1420,7 +1347,8 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV) {  /// EmitStoreThroughLValue - Store the specified rvalue into the specified  /// lvalue, where both are guaranteed to the have the same type, and that type  /// is 'Ty'. -void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit) { +void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, +                                             bool isInit) {    if (!Dst.isSimple()) {      if (Dst.isVectorElt()) {        // Read/modify/write the vector, inserting the new element. @@ -1489,7 +1417,7 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit        llvm::Value *RHS = EmitScalarExpr(Dst.getBaseIvarExp());        llvm::Value *dst = RHS;        RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast"); -      llvm::Value *LHS =  +      llvm::Value *LHS =          Builder.CreatePtrToInt(LvalueDst, ResultType, "sub.ptr.lhs.cast");        llvm::Value *BytesBetween = Builder.CreateSub(LHS, RHS, "ivar.offset");        CGM.getObjCRuntime().EmitObjCIvarAssign(*this, src, dst, @@ -1625,6 +1553,12 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,        for (unsigned i = 0; i != NumDstElts; ++i)          Mask.push_back(Builder.getInt32(i)); +      // When the vector size is odd and .odd or .hi is used, the last element +      // of the Elts constant array will be one past the size of the vector. +      // Ignore the last element here, if it is greater than the mask size. +      if (getAccessedFieldNo(NumSrcElts - 1, Elts) == Mask.size()) +        NumSrcElts--; +        // modify when what gets shuffled in        for (unsigned i = 0; i != NumSrcElts; ++i)          Mask[getAccessedFieldNo(i, Elts)] = Builder.getInt32(i+NumDstElts); @@ -1654,12 +1588,12 @@ static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,                                   bool IsMemberAccess=false) {    if (Ctx.getLangOpts().getGC() == LangOptions::NonGC)      return; -   +    if (isa<ObjCIvarRefExpr>(E)) {      QualType ExpTy = E->getType();      if (IsMemberAccess && ExpTy->isPointerType()) {        // If ivar is a structure pointer, assigning to field of -      // this struct follows gcc's behavior and makes it a non-ivar  +      // this struct follows gcc's behavior and makes it a non-ivar        // writer-barrier conservatively.        ExpTy = ExpTy->getAs<PointerType>()->getPointeeType();        if (ExpTy->isRecordType()) { @@ -1673,7 +1607,7 @@ static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,      LV.setObjCArray(E->getType()->isArrayType());      return;    } -   +    if (const DeclRefExpr *Exp = dyn_cast<DeclRefExpr>(E)) {      if (const VarDecl *VD = dyn_cast<VarDecl>(Exp->getDecl())) {        if (VD->hasGlobalStorage()) { @@ -1684,12 +1618,12 @@ static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,      LV.setObjCArray(E->getType()->isArrayType());      return;    } -   +    if (const UnaryOperator *Exp = dyn_cast<UnaryOperator>(E)) {      setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);      return;    } -   +    if (const ParenExpr *Exp = dyn_cast<ParenExpr>(E)) {      setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);      if (LV.isObjCIvar()) { @@ -1699,7 +1633,7 @@ static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,        if (ExpTy->isPointerType())          ExpTy = ExpTy->getAs<PointerType>()->getPointeeType();        if (ExpTy->isRecordType()) -        LV.setObjCIvar(false);  +        LV.setObjCIvar(false);      }      return;    } @@ -1713,7 +1647,7 @@ static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,      setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);      return;    } -   +    if (const CStyleCastExpr *Exp = dyn_cast<CStyleCastExpr>(E)) {      setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);      return; @@ -1726,12 +1660,12 @@ static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,    if (const ArraySubscriptExpr *Exp = dyn_cast<ArraySubscriptExpr>(E)) {      setObjCGCLValueClass(Ctx, Exp->getBase(), LV); -    if (LV.isObjCIvar() && !LV.isObjCArray())  -      // Using array syntax to assigning to what an ivar points to is not  +    if (LV.isObjCIvar() && !LV.isObjCArray()) +      // Using array syntax to assigning to what an ivar points to is not        // same as assigning to the ivar itself. {id *Names;} Names[i] = 0; -      LV.setObjCIvar(false);  +      LV.setObjCIvar(false);      else if (LV.isGlobalObjCRef() && !LV.isObjCArray()) -      // Using array syntax to assigning to what global points to is not  +      // Using array syntax to assigning to what global points to is not        // same as assigning to the global itself. {id *G;} G[i] = 0;        LV.setGlobalObjCRef(false);      return; @@ -1793,6 +1727,13 @@ static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF,    return CGF.MakeAddrLValue(V, E->getType(), Alignment);  } +static LValue EmitCapturedFieldLValue(CodeGenFunction &CGF, const FieldDecl *FD, +                                      llvm::Value *ThisValue) { +  QualType TagType = CGF.getContext().getTagDeclType(FD->getParent()); +  LValue LV = CGF.MakeNaturalAlignAddrLValue(ThisValue, TagType); +  return CGF.EmitLValueForField(LV, FD); +} +  LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {    const NamedDecl *ND = E->getDecl();    CharUnits Alignment = getContext().getDeclAlign(ND); @@ -1838,16 +1779,17 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {      bool isBlockVariable = VD->hasAttr<BlocksAttr>();      llvm::Value *V = LocalDeclMap.lookup(VD); -    if (!V && VD->isStaticLocal())  +    if (!V && VD->isStaticLocal())        V = CGM.getStaticLocalDeclAddress(VD);      // Use special handling for lambdas.      if (!V) {        if (FieldDecl *FD = LambdaCaptureFields.lookup(VD)) { -        QualType LambdaTagType = getContext().getTagDeclType(FD->getParent()); -        LValue LambdaLV = MakeNaturalAlignAddrLValue(CXXABIThisValue, -                                                     LambdaTagType); -        return EmitLValueForField(LambdaLV, FD); +        return EmitCapturedFieldLValue(*this, FD, CXXABIThisValue); +      } else if (CapturedStmtInfo) { +        if (const FieldDecl *FD = CapturedStmtInfo->lookup(VD)) +          return EmitCapturedFieldLValue(*this, FD, +                                         CapturedStmtInfo->getContextValue());        }        assert(isa<BlockDecl>(CurCodeDecl) && E->refersToEnclosingLocal()); @@ -1888,8 +1830,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {      return LV;    } -  if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(ND)) -    return EmitFunctionDeclLValue(*this, E, fn); +  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) +    return EmitFunctionDeclLValue(*this, E, FD);    llvm_unreachable("Unhandled DeclRefExpr");  } @@ -1945,7 +1887,7 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {    case UO_PreDec: {      LValue LV = EmitLValue(E->getSubExpr());      bool isInc = E->getOpcode() == UO_PreInc; -     +      if (E->getType()->isAnyComplexType())        EmitComplexPrePostIncDec(E, LV, isInc, true/*isPre*/);      else @@ -2008,8 +1950,9 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {    case PredefinedExpr::Func:    case PredefinedExpr::Function:    case PredefinedExpr::LFunction: +  case PredefinedExpr::FuncDName:    case PredefinedExpr::PrettyFunction: { -    unsigned IdentType = E->getIdentType(); +    PredefinedExpr::IdentType IdentType = E->getIdentType();      std::string GlobalVarName;      switch (IdentType) { @@ -2020,6 +1963,9 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {      case PredefinedExpr::Function:        GlobalVarName = "__FUNCTION__.";        break; +    case PredefinedExpr::FuncDName: +      GlobalVarName = "__FUNCDNAME__."; +      break;      case PredefinedExpr::LFunction:        GlobalVarName = "L__FUNCTION__.";        break; @@ -2033,17 +1979,28 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {        FnName = FnName.substr(1);      GlobalVarName += FnName; +    // If this is outside of a function use the top level decl.      const Decl *CurDecl = CurCodeDecl; -    if (CurDecl == 0) +    if (CurDecl == 0 || isa<VarDecl>(CurDecl))        CurDecl = getContext().getTranslationUnitDecl(); -    std::string FunctionName = -        (isa<BlockDecl>(CurDecl) -         ? FnName.str() -         : PredefinedExpr::ComputeName((PredefinedExpr::IdentType)IdentType, -                                       CurDecl)); +    const Type *ElemType = E->getType()->getArrayElementTypeNoTypeQual(); +    std::string FunctionName; +    if (isa<BlockDecl>(CurDecl)) { +      // Blocks use the mangled function name. +      // FIXME: ComputeName should handle blocks. +      FunctionName = FnName.str(); +    } else if (isa<CapturedDecl>(CurDecl)) { +      // For a captured statement, the function name is its enclosing +      // function name not the one compiler generated. +      FunctionName = PredefinedExpr::ComputeName(IdentType, CurDecl); +    } else { +      FunctionName = PredefinedExpr::ComputeName(IdentType, CurDecl); +      assert(cast<ConstantArrayType>(E->getType())->getSize() - 1 == +                 FunctionName.size() && +             "Computed __func__ length differs from type!"); +    } -    const Type* ElemType = E->getType()->getArrayElementTypeNoTypeQual();      llvm::Constant *C;      if (ElemType->isWideCharType()) {        SmallString<32> RawChars; @@ -2076,7 +2033,10 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {  /// followed by an array of i8 containing the type name. TypeKind is 0 for an  /// integer, 1 for a floating point value, and -1 for anything else.  llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) { -  // FIXME: Only emit each type's descriptor once. +  // Only emit each type's descriptor once. +  if (llvm::Constant *C = CGM.getTypeDescriptor(T)) +    return C; +    uint16_t TypeKind = -1;    uint16_t TypeInfo = 0; @@ -2109,6 +2069,10 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {                               llvm::GlobalVariable::PrivateLinkage,                               Descriptor);    GV->setUnnamedAddr(true); + +  // Remember the descriptor for this type. +  CGM.setTypeDescriptor(T, GV); +    return GV;  } @@ -2151,12 +2115,10 @@ llvm::Constant *CodeGenFunction::EmitCheckSourceLocation(SourceLocation Loc) {    PresumedLoc PLoc = getContext().getSourceManager().getPresumedLoc(Loc);    llvm::Constant *Data[] = { -    // FIXME: Only emit each file name once. -    PLoc.isValid() ? cast<llvm::Constant>( -                       Builder.CreateGlobalStringPtr(PLoc.getFilename())) +    PLoc.isValid() ? CGM.GetAddrOfConstantCString(PLoc.getFilename(), ".src")                     : llvm::Constant::getNullValue(Int8PtrTy), -    Builder.getInt32(PLoc.getLine()), -    Builder.getInt32(PLoc.getColumn()) +    Builder.getInt32(PLoc.isValid() ? PLoc.getLine() : 0), +    Builder.getInt32(PLoc.isValid() ? PLoc.getColumn() : 0)    };    return llvm::ConstantStruct::getAnon(Data); @@ -2271,12 +2233,12 @@ static const Expr *isSimpleArrayDecayOperand(const Expr *E) {    const CastExpr *CE = dyn_cast<CastExpr>(E);    if (CE == 0 || CE->getCastKind() != CK_ArrayToPointerDecay)      return 0; -   +    // If this is a decay from variable width array, bail out.    const Expr *SubExpr = CE->getSubExpr();    if (SubExpr->getType()->isVariableArrayType())      return 0; -   +    return SubExpr;  } @@ -2287,7 +2249,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,    QualType IdxTy  = E->getIdx()->getType();    bool IdxSigned = IdxTy->isSignedIntegerOrEnumerationType(); -  if (SanOpts->Bounds) +  if (SanOpts->ArrayBounds)      EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, Accessed);    // If the base is a vector type, then we are forming a vector element lvalue @@ -2360,7 +2322,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,      llvm::Value *ArrayPtr = ArrayLV.getAddress();      llvm::Value *Zero = llvm::ConstantInt::get(Int32Ty, 0);      llvm::Value *Args[] = { Zero, Idx }; -     +      // Propagate the alignment from the array itself to the result.      ArrayAlignment = ArrayLV.getAlignment(); @@ -2381,7 +2343,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,    assert(!T.isNull() &&           "CodeGenFunction::EmitArraySubscriptExpr(): Illegal base type"); -   +    // Limit the alignment to that of the result type.    LValue LV;    if (!ArrayAlignment.isZero()) { @@ -2404,7 +2366,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,  static  llvm::Constant *GenerateConstantVector(CGBuilderTy &Builder, -                                       SmallVector<unsigned, 4> &Elts) { +                                       SmallVectorImpl<unsigned> &Elts) {    SmallVector<llvm::Constant*, 4> CElts;    for (unsigned i = 0, e = Elts.size(); i != e; ++i)      CElts.push_back(Builder.getInt32(Elts[i])); @@ -2435,7 +2397,7 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {      assert(E->getBase()->getType()->isVectorType() &&             "Result must be a vector");      llvm::Value *Vec = EmitScalarExpr(E->getBase()); -     +      // Store the vector to memory (because LValue wants an address).      llvm::Value *VecMem = CreateMemTemp(E->getBase()->getType());      Builder.CreateStore(Vec, VecMem); @@ -2444,7 +2406,7 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {    QualType type =      E->getType().withCVRQualifiers(Base.getQuals().getCVRQualifiers()); -   +    // Encode the element access list into a vector of unsigned indices.    SmallVector<unsigned, 4> Indices;    E->getEncodedElementAccess(Indices); @@ -2485,7 +2447,7 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {      setObjCGCLValueClass(getContext(), E, LV);      return LV;    } -   +    if (VarDecl *VD = dyn_cast<VarDecl>(ND))      return EmitGlobalVarDeclLValue(*this, E, VD); @@ -2567,7 +2529,8 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,            tbaa = CGM.getTBAAInfo(getContext().CharTy);          else            tbaa = CGM.getTBAAInfo(type); -        CGM.DecorateInstruction(load, tbaa); +        if (tbaa) +          CGM.DecorateInstruction(load, tbaa);        }        addr = load; @@ -2580,7 +2543,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,        cvr = 0; // qualifiers don't recursively apply to referencee      }    } -   +    // Make sure that the address is pointing to the right type.  This is critical    // for both unions and structs.  A union needs a bitcast, a struct element    // will need a bitcast if the LLVM type laid out doesn't match the desired @@ -2618,11 +2581,11 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,    return LV;  } -LValue  -CodeGenFunction::EmitLValueForFieldInitialization(LValue Base,  +LValue +CodeGenFunction::EmitLValueForFieldInitialization(LValue Base,                                                    const FieldDecl *Field) {    QualType FieldType = Field->getType(); -   +    if (!FieldType->isReferenceType())      return EmitLValueForField(Base, Field); @@ -2657,7 +2620,7 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){    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()); @@ -2705,19 +2668,19 @@ EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {    ConditionalEvaluation eval(*this);    EmitBranchOnBoolExpr(condExpr, lhsBlock, rhsBlock); -     +    // Any temporaries created here are conditional.    EmitBlock(lhsBlock);    eval.begin(*this);    LValue lhs = EmitLValue(expr->getTrueExpr());    eval.end(*this); -     +    if (!lhs.isSimple())      return EmitUnsupportedLValue(expr, "conditional operator");    lhsBlock = Builder.GetInsertBlock();    Builder.CreateBr(contBlock); -     +    // Any temporaries created here are conditional.    EmitBlock(rhsBlock);    eval.begin(*this); @@ -2746,26 +2709,6 @@ EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {  LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {    switch (E->getCastKind()) {    case CK_ToVoid: -    return EmitUnsupportedLValue(E, "unexpected cast lvalue"); - -  case CK_Dependent: -    llvm_unreachable("dependent cast kind in IR gen!"); - -  case CK_BuiltinFnToFnPtr: -    llvm_unreachable("builtin functions are handled elsewhere"); - -  // These two casts are currently treated as no-ops, although they could -  // potentially be real operations depending on the target's ABI. -  case CK_NonAtomicToAtomic: -  case CK_AtomicToNonAtomic: - -  case CK_NoOp: -  case CK_LValueToRValue: -    if (!E->getSubExpr()->Classify(getContext()).isPRValue()  -        || E->getType()->isRecordType()) -      return EmitLValue(E->getSubExpr()); -    // Fall through to synthesize a temporary. -    case CK_BitCast:    case CK_ArrayToPointerDecay:    case CK_FunctionToPointerDecay: @@ -2799,16 +2742,20 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {    case CK_ARCProduceObject:    case CK_ARCConsumeObject:    case CK_ARCReclaimReturnedObject: -  case CK_ARCExtendBlockObject:  -  case CK_CopyAndAutoreleaseBlockObject: { -    // These casts only produce lvalues when we're binding a reference to a  -    // temporary realized from a (converted) pure rvalue. Emit the expression -    // as a value, copy it into a temporary, and return an lvalue referring to -    // that temporary. -    llvm::Value *V = CreateMemTemp(E->getType(), "ref.temp"); -    EmitAnyExprToMem(E, V, E->getType().getQualifiers(), false); -    return MakeAddrLValue(V, E->getType()); -  } +  case CK_ARCExtendBlockObject: +  case CK_CopyAndAutoreleaseBlockObject: +    return EmitUnsupportedLValue(E, "unexpected cast lvalue"); + +  case CK_Dependent: +    llvm_unreachable("dependent cast kind in IR gen!"); + +  case CK_BuiltinFnToFnPtr: +    llvm_unreachable("builtin functions are handled elsewhere"); + +  // These are never l-values; just use the aggregate emission code. +  case CK_NonAtomicToAtomic: +  case CK_AtomicToNonAtomic: +    return EmitAggExprToLValue(E);    case CK_Dynamic: {      LValue LV = EmitLValue(E->getSubExpr()); @@ -2821,53 +2768,55 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {    case CK_UserDefinedConversion:    case CK_CPointerToObjCPointerCast:    case CK_BlockPointerToObjCPointerCast: +  case CK_NoOp: +  case CK_LValueToRValue:      return EmitLValue(E->getSubExpr()); -   +    case CK_UncheckedDerivedToBase:    case CK_DerivedToBase: { -    const RecordType *DerivedClassTy =  +    const RecordType *DerivedClassTy =        E->getSubExpr()->getType()->getAs<RecordType>(); -    CXXRecordDecl *DerivedClassDecl =  +    CXXRecordDecl *DerivedClassDecl =        cast<CXXRecordDecl>(DerivedClassTy->getDecl()); -     +      LValue LV = EmitLValue(E->getSubExpr());      llvm::Value *This = LV.getAddress(); -     +      // Perform the derived-to-base conversion -    llvm::Value *Base =  -      GetAddressOfBaseClass(This, DerivedClassDecl,  +    llvm::Value *Base = +      GetAddressOfBaseClass(This, DerivedClassDecl,                              E->path_begin(), E->path_end(),                              /*NullCheckValue=*/false); -     +      return MakeAddrLValue(Base, E->getType());    }    case CK_ToUnion:      return EmitAggExprToLValue(E);    case CK_BaseToDerived: {      const RecordType *DerivedClassTy = E->getType()->getAs<RecordType>(); -    CXXRecordDecl *DerivedClassDecl =  +    CXXRecordDecl *DerivedClassDecl =        cast<CXXRecordDecl>(DerivedClassTy->getDecl()); -     +      LValue LV = EmitLValue(E->getSubExpr()); +    // Perform the base-to-derived conversion +    llvm::Value *Derived = +      GetAddressOfDerivedClass(LV.getAddress(), DerivedClassDecl, +                               E->path_begin(), E->path_end(), +                               /*NullCheckValue=*/false); +      // C++11 [expr.static.cast]p2: Behavior is undefined if a downcast is      // performed and the object is not of the derived type.      if (SanitizePerformTypeCheck)        EmitTypeCheck(TCK_DowncastReference, E->getExprLoc(), -                    LV.getAddress(), E->getType()); +                    Derived, E->getType()); -    // Perform the base-to-derived conversion -    llvm::Value *Derived =  -      GetAddressOfDerivedClass(LV.getAddress(), DerivedClassDecl,  -                               E->path_begin(), E->path_end(), -                               /*NullCheckValue=*/false); -          return MakeAddrLValue(Derived, E->getType());    }    case CK_LValueBitCast: {      // This must be a reinterpret_cast (or c-style equivalent).      const ExplicitCastExpr *CE = cast<ExplicitCastExpr>(E); -     +      LValue LV = EmitLValue(E->getSubExpr());      llvm::Value *V = Builder.CreateBitCast(LV.getAddress(),                                             ConvertType(CE->getTypeAsWritten())); @@ -2876,23 +2825,15 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {    case CK_ObjCObjectLValueCast: {      LValue LV = EmitLValue(E->getSubExpr());      QualType ToType = getContext().getLValueReferenceType(E->getType()); -    llvm::Value *V = Builder.CreateBitCast(LV.getAddress(),  +    llvm::Value *V = Builder.CreateBitCast(LV.getAddress(),                                             ConvertType(ToType));      return MakeAddrLValue(V, E->getType());    }    case CK_ZeroToOCLEvent:      llvm_unreachable("NULL to OpenCL event lvalue cast is not valid");    } -   -  llvm_unreachable("Unhandled lvalue cast kind?"); -} -LValue CodeGenFunction::EmitNullInitializationLValue( -                                              const CXXScalarValueInitExpr *E) { -  QualType Ty = E->getType(); -  LValue LV = MakeAddrLValue(CreateMemTemp(Ty), Ty); -  EmitNullInitialization(LV.getAddress(), Ty); -  return LV; +  llvm_unreachable("Unhandled lvalue cast kind?");  }  LValue CodeGenFunction::EmitOpaqueValueLValue(const OpaqueValueExpr *e) { @@ -2900,23 +2841,18 @@ LValue CodeGenFunction::EmitOpaqueValueLValue(const OpaqueValueExpr *e) {    return getOpaqueLValueMapping(e);  } -LValue CodeGenFunction::EmitMaterializeTemporaryExpr( -                                           const MaterializeTemporaryExpr *E) { -  RValue RV = EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0); -  return MakeAddrLValue(RV.getScalarVal(), E->getType()); -} -  RValue CodeGenFunction::EmitRValueForField(LValue LV, -                                           const FieldDecl *FD) { +                                           const FieldDecl *FD, +                                           SourceLocation Loc) {    QualType FT = FD->getType();    LValue FieldLV = EmitLValueForField(LV, FD);    switch (getEvaluationKind(FT)) {    case TEK_Complex: -    return RValue::getComplex(EmitLoadOfComplex(FieldLV)); +    return RValue::getComplex(EmitLoadOfComplex(FieldLV, Loc));    case TEK_Aggregate:      return FieldLV.asAggregateRValue();    case TEK_Scalar: -    return EmitLoadOfLValue(FieldLV); +    return EmitLoadOfLValue(FieldLV, Loc);    }    llvm_unreachable("bad evaluation kind");  } @@ -2925,7 +2861,7 @@ RValue CodeGenFunction::EmitRValueForField(LValue LV,  //                             Expression Emission  //===--------------------------------------------------------------------===// -RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,  +RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,                                       ReturnValueSlot ReturnValue) {    if (CGDebugInfo *DI = getDebugInfo()) {      SourceLocation Loc = E->getLocStart(); @@ -2956,7 +2892,7 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,      if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(TargetDecl))        return EmitCXXOperatorMemberCallExpr(CE, MD, ReturnValue); -  if (const CXXPseudoDestructorExpr *PseudoDtor  +  if (const CXXPseudoDestructorExpr *PseudoDtor            = dyn_cast<CXXPseudoDestructorExpr>(E->getCallee()->IgnoreParens())) {      QualType DestroyedType = PseudoDtor->getDestroyedType();      if (getLangOpts().ObjCAutoRefCount && @@ -2969,7 +2905,7 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,        Expr *BaseExpr = PseudoDtor->getBase();        llvm::Value *BaseValue = NULL;        Qualifiers BaseQuals; -       +        // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.        if (PseudoDtor->isArrow()) {          BaseValue = EmitScalarExpr(BaseExpr); @@ -2981,15 +2917,15 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,          QualType BaseTy = BaseExpr->getType();          BaseQuals = BaseTy.getQualifiers();        } -           +        switch (PseudoDtor->getDestroyedType().getObjCLifetime()) {        case Qualifiers::OCL_None:        case Qualifiers::OCL_ExplicitNone:        case Qualifiers::OCL_Autoreleasing:          break; -         +        case Qualifiers::OCL_Strong: -        EmitARCRelease(Builder.CreateLoad(BaseValue,  +        EmitARCRelease(Builder.CreateLoad(BaseValue,                            PseudoDtor->getDestroyedType().isVolatileQualified()),                         ARCPreciseLifetime);          break; @@ -3003,16 +2939,16 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,        //   The result shall only be used as the operand for the function call        //   operator (), and the result of such a call has type void. The only        //   effect is the evaluation of the postfix-expression before the dot or -      //   arrow.       +      //   arrow.        EmitScalarExpr(E->getCallee());      } -     +      return RValue::get(0);    }    llvm::Value *Callee = EmitScalarExpr(E->getCallee()); -  return EmitCall(E->getCallee()->getType(), Callee, ReturnValue, -                  E->arg_begin(), E->arg_end(), TargetDecl); +  return EmitCall(E->getCallee()->getType(), Callee, E->getLocStart(), +                  ReturnValue, E->arg_begin(), E->arg_end(), TargetDecl);  }  LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) { @@ -3068,7 +3004,7 @@ LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) {    if (!RV.isScalar())      return MakeAddrLValue(RV.getAggregateAddr(), E->getType()); -     +    assert(E->getCallReturnType()->isReferenceType() &&           "Can't have a scalar return unless the return type is a "           "reference type!"); @@ -3095,7 +3031,8 @@ CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) {  }  llvm::Value *CodeGenFunction::EmitCXXUuidofExpr(const CXXUuidofExpr *E) { -  return CGM.GetAddrOfUuidDescriptor(E); +  return Builder.CreateBitCast(CGM.GetAddrOfUuidDescriptor(E), +                               ConvertType(E->getType())->getPointerTo());  }  LValue CodeGenFunction::EmitCXXUuidofLValue(const CXXUuidofExpr *E) { @@ -3120,19 +3057,19 @@ CodeGenFunction::EmitLambdaLValue(const LambdaExpr *E) {  LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {    RValue RV = EmitObjCMessageExpr(E); -   +    if (!RV.isScalar())      return MakeAddrLValue(RV.getAggregateAddr(), E->getType()); -   +    assert(E->getMethodDecl()->getResultType()->isReferenceType() &&           "Can't have a scalar return unless the return type is a "           "reference type!"); -   +    return MakeAddrLValue(RV.getScalarVal(), E->getType());  }  LValue CodeGenFunction::EmitObjCSelectorLValue(const ObjCSelectorExpr *E) { -  llvm::Value *V =  +  llvm::Value *V =      CGM.getObjCRuntime().GetSelector(*this, E->getSelector(), true);    return MakeAddrLValue(V, E->getType());  } @@ -3168,7 +3105,7 @@ LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) {      BaseQuals = ObjectTy.getQualifiers();    } -  LValue LV =  +  LValue LV =      EmitLValueForIvar(ObjectTy, BaseValue, E->getDecl(),                        BaseQuals.getCVRQualifiers());    setObjCGCLValueClass(getContext(), E, LV); @@ -3182,6 +3119,7 @@ LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) {  }  RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee, +                                 SourceLocation CallLoc,                                   ReturnValueSlot ReturnValue,                                   CallExpr::const_arg_iterator ArgBeg,                                   CallExpr::const_arg_iterator ArgEnd, @@ -3196,8 +3134,60 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,    const FunctionType *FnType      = cast<FunctionType>(cast<PointerType>(CalleeType)->getPointeeType()); +  // Force column info to differentiate multiple inlined call sites on +  // the same line, analoguous to EmitCallExpr. +  bool ForceColumnInfo = false; +  if (const FunctionDecl* FD = dyn_cast_or_null<const FunctionDecl>(TargetDecl)) +    ForceColumnInfo = FD->isInlineSpecified(); + +  if (getLangOpts().CPlusPlus && SanOpts->Function && +      (!TargetDecl || !isa<FunctionDecl>(TargetDecl))) { +    if (llvm::Constant *PrefixSig = +            CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) { +      llvm::Constant *FTRTTIConst = +          CGM.GetAddrOfRTTIDescriptor(QualType(FnType, 0), /*ForEH=*/true); +      llvm::Type *PrefixStructTyElems[] = { +        PrefixSig->getType(), +        FTRTTIConst->getType() +      }; +      llvm::StructType *PrefixStructTy = llvm::StructType::get( +          CGM.getLLVMContext(), PrefixStructTyElems, /*isPacked=*/true); + +      llvm::Value *CalleePrefixStruct = Builder.CreateBitCast( +          Callee, llvm::PointerType::getUnqual(PrefixStructTy)); +      llvm::Value *CalleeSigPtr = +          Builder.CreateConstGEP2_32(CalleePrefixStruct, 0, 0); +      llvm::Value *CalleeSig = Builder.CreateLoad(CalleeSigPtr); +      llvm::Value *CalleeSigMatch = Builder.CreateICmpEQ(CalleeSig, PrefixSig); + +      llvm::BasicBlock *Cont = createBasicBlock("cont"); +      llvm::BasicBlock *TypeCheck = createBasicBlock("typecheck"); +      Builder.CreateCondBr(CalleeSigMatch, TypeCheck, Cont); + +      EmitBlock(TypeCheck); +      llvm::Value *CalleeRTTIPtr = +          Builder.CreateConstGEP2_32(CalleePrefixStruct, 0, 1); +      llvm::Value *CalleeRTTI = Builder.CreateLoad(CalleeRTTIPtr); +      llvm::Value *CalleeRTTIMatch = +          Builder.CreateICmpEQ(CalleeRTTI, FTRTTIConst); +      llvm::Constant *StaticData[] = { +        EmitCheckSourceLocation(CallLoc), +        EmitCheckTypeDescriptor(CalleeType) +      }; +      EmitCheck(CalleeRTTIMatch, +                "function_type_mismatch", +                StaticData, +                Callee, +                CRK_Recoverable); + +      Builder.CreateBr(Cont); +      EmitBlock(Cont); +    } +  } +    CallArgList Args; -  EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), ArgBeg, ArgEnd); +  EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), ArgBeg, ArgEnd, +               ForceColumnInfo);    const CGFunctionInfo &FnInfo =      CGM.getTypes().arrangeFreeFunctionCall(Args, FnType); @@ -3250,15 +3240,16 @@ EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) {  /// Given the address of a temporary variable, produce an r-value of  /// its type.  RValue CodeGenFunction::convertTempToRValue(llvm::Value *addr, -                                            QualType type) { +                                            QualType type, +                                            SourceLocation loc) {    LValue lvalue = MakeNaturalAlignAddrLValue(addr, type);    switch (getEvaluationKind(type)) {    case TEK_Complex: -    return RValue::getComplex(EmitLoadOfComplex(lvalue)); +    return RValue::getComplex(EmitLoadOfComplex(lvalue, loc));    case TEK_Aggregate:      return lvalue.asAggregateRValue();    case TEK_Scalar: -    return RValue::get(EmitLoadOfScalar(lvalue)); +    return RValue::get(EmitLoadOfScalar(lvalue, loc));    }    llvm_unreachable("bad evaluation kind");  } diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index b974e1dcc6820..9d0f3a9661a68 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -29,14 +29,6 @@ using namespace CodeGen;  //                        Aggregate Expression Emitter  //===----------------------------------------------------------------------===// -llvm::Value *AggValueSlot::getPaddedAtomicAddr() const { -  assert(isValueOfAtomic()); -  llvm::GEPOperator *op = cast<llvm::GEPOperator>(getAddr()); -  assert(op->getNumIndices() == 2); -  assert(op->hasAllZeroIndices()); -  return op->getPointerOperand(); -} -  namespace  {  class AggExprEmitter : public StmtVisitor<AggExprEmitter> {    CodeGenFunction &CGF; @@ -91,7 +83,6 @@ public:    void EmitMoveFromReturnSlot(const Expr *E, RValue Src); -  void EmitStdInitializerList(llvm::Value *DestPtr, InitListExpr *InitList);    void EmitArrayInit(llvm::Value *DestPtr, llvm::ArrayType *AType,                       QualType elementType, InitListExpr *E); @@ -177,6 +168,7 @@ public:    void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);    void VisitCXXConstructExpr(const CXXConstructExpr *E);    void VisitLambdaExpr(LambdaExpr *E); +  void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);    void VisitExprWithCleanups(ExprWithCleanups *E);    void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);    void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); } @@ -202,38 +194,6 @@ public:      CGF.EmitAtomicExpr(E, EnsureSlot(E->getType()).getAddr());    }  }; - -/// A helper class for emitting expressions into the value sub-object -/// of a padded atomic type. -class ValueDestForAtomic { -  AggValueSlot Dest; -public: -  ValueDestForAtomic(CodeGenFunction &CGF, AggValueSlot dest, QualType type) -    : Dest(dest) { -    assert(!Dest.isValueOfAtomic()); -    if (!Dest.isIgnored() && CGF.CGM.isPaddedAtomicType(type)) { -      llvm::Value *valueAddr = CGF.Builder.CreateStructGEP(Dest.getAddr(), 0); -      Dest = AggValueSlot::forAddr(valueAddr, -                                   Dest.getAlignment(), -                                   Dest.getQualifiers(), -                                   Dest.isExternallyDestructed(), -                                   Dest.requiresGCollection(), -                                   Dest.isPotentiallyAliased(), -                                   Dest.isZeroed(), -                                   AggValueSlot::IsValueOfAtomic); -    } -  } - -  const AggValueSlot &getDest() const { return Dest; } - -  ~ValueDestForAtomic() { -    // Kill the GEP if we made one and it didn't end up used. -    if (Dest.isValueOfAtomic()) { -      llvm::Instruction *addr = cast<llvm::GetElementPtrInst>(Dest.getAddr()); -      if (addr->use_empty()) addr->eraseFromParent(); -    } -  } -};  }  // end anonymous namespace.  //===----------------------------------------------------------------------===// @@ -248,8 +208,7 @@ void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {    // If the type of the l-value is atomic, then do an atomic load.    if (LV.getType()->isAtomicType()) { -    ValueDestForAtomic valueDest(CGF, Dest, LV.getType()); -    CGF.EmitAtomicLoad(LV, valueDest.getDest()); +    CGF.EmitAtomicLoad(LV, E->getExprLoc(), Dest);      return;    } @@ -345,89 +304,70 @@ void AggExprEmitter::EmitCopy(QualType type, const AggValueSlot &dest,                          std::min(dest.getAlignment(), src.getAlignment()));  } -static QualType GetStdInitializerListElementType(QualType T) { -  // Just assume that this is really std::initializer_list. -  ClassTemplateSpecializationDecl *specialization = -      cast<ClassTemplateSpecializationDecl>(T->castAs<RecordType>()->getDecl()); -  return specialization->getTemplateArgs()[0].getAsType(); -} - -/// \brief Prepare cleanup for the temporary array. -static void EmitStdInitializerListCleanup(CodeGenFunction &CGF, -                                          QualType arrayType, -                                          llvm::Value *addr, -                                          const InitListExpr *initList) { -  QualType::DestructionKind dtorKind = arrayType.isDestructedType(); -  if (!dtorKind) -    return; // Type doesn't need destroying. -  if (dtorKind != QualType::DK_cxx_destructor) { -    CGF.ErrorUnsupported(initList, "ObjC ARC type in initializer_list"); -    return; -  } - -  CodeGenFunction::Destroyer *destroyer = CGF.getDestroyer(dtorKind); -  CGF.pushDestroy(NormalAndEHCleanup, addr, arrayType, destroyer, -                  /*EHCleanup=*/true); -} -  /// \brief Emit the initializer for a std::initializer_list initialized with a  /// real initializer list. -void AggExprEmitter::EmitStdInitializerList(llvm::Value *destPtr, -                                            InitListExpr *initList) { -  // We emit an array containing the elements, then have the init list point -  // at the array. -  ASTContext &ctx = CGF.getContext(); -  unsigned numInits = initList->getNumInits(); -  QualType element = GetStdInitializerListElementType(initList->getType()); -  llvm::APInt size(ctx.getTypeSize(ctx.getSizeType()), numInits); -  QualType array = ctx.getConstantArrayType(element, size, ArrayType::Normal,0); -  llvm::Type *LTy = CGF.ConvertTypeForMem(array); -  llvm::AllocaInst *alloc = CGF.CreateTempAlloca(LTy); -  alloc->setAlignment(ctx.getTypeAlignInChars(array).getQuantity()); -  alloc->setName(".initlist."); - -  EmitArrayInit(alloc, cast<llvm::ArrayType>(LTy), element, initList); - -  // FIXME: The diagnostics are somewhat out of place here. -  RecordDecl *record = initList->getType()->castAs<RecordType>()->getDecl(); -  RecordDecl::field_iterator field = record->field_begin(); -  if (field == record->field_end()) { -    CGF.ErrorUnsupported(initList, "weird std::initializer_list"); +void +AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { +  // Emit an array containing the elements.  The array is externally destructed +  // if the std::initializer_list object is. +  ASTContext &Ctx = CGF.getContext(); +  LValue Array = CGF.EmitLValue(E->getSubExpr()); +  assert(Array.isSimple() && "initializer_list array not a simple lvalue"); +  llvm::Value *ArrayPtr = Array.getAddress(); + +  const ConstantArrayType *ArrayType = +      Ctx.getAsConstantArrayType(E->getSubExpr()->getType()); +  assert(ArrayType && "std::initializer_list constructed from non-array"); + +  // FIXME: Perform the checks on the field types in SemaInit. +  RecordDecl *Record = E->getType()->castAs<RecordType>()->getDecl(); +  RecordDecl::field_iterator Field = Record->field_begin(); +  if (Field == Record->field_end()) { +    CGF.ErrorUnsupported(E, "weird std::initializer_list");      return;    } -  QualType elementPtr = ctx.getPointerType(element.withConst()); -    // Start pointer. -  if (!ctx.hasSameType(field->getType(), elementPtr)) { -    CGF.ErrorUnsupported(initList, "weird std::initializer_list"); +  if (!Field->getType()->isPointerType() || +      !Ctx.hasSameType(Field->getType()->getPointeeType(), +                       ArrayType->getElementType())) { +    CGF.ErrorUnsupported(E, "weird std::initializer_list");      return;    } -  LValue DestLV = CGF.MakeNaturalAlignAddrLValue(destPtr, initList->getType()); -  LValue start = CGF.EmitLValueForFieldInitialization(DestLV, *field); -  llvm::Value *arrayStart = Builder.CreateStructGEP(alloc, 0, "arraystart"); -  CGF.EmitStoreThroughLValue(RValue::get(arrayStart), start); -  ++field; - -  if (field == record->field_end()) { -    CGF.ErrorUnsupported(initList, "weird std::initializer_list"); + +  AggValueSlot Dest = EnsureSlot(E->getType()); +  LValue DestLV = CGF.MakeAddrLValue(Dest.getAddr(), E->getType(), +                                     Dest.getAlignment()); +  LValue Start = CGF.EmitLValueForFieldInitialization(DestLV, *Field); +  llvm::Value *Zero = llvm::ConstantInt::get(CGF.PtrDiffTy, 0); +  llvm::Value *IdxStart[] = { Zero, Zero }; +  llvm::Value *ArrayStart = +      Builder.CreateInBoundsGEP(ArrayPtr, IdxStart, "arraystart"); +  CGF.EmitStoreThroughLValue(RValue::get(ArrayStart), Start); +  ++Field; + +  if (Field == Record->field_end()) { +    CGF.ErrorUnsupported(E, "weird std::initializer_list");      return;    } -  LValue endOrLength = CGF.EmitLValueForFieldInitialization(DestLV, *field); -  if (ctx.hasSameType(field->getType(), elementPtr)) { + +  llvm::Value *Size = Builder.getInt(ArrayType->getSize()); +  LValue EndOrLength = CGF.EmitLValueForFieldInitialization(DestLV, *Field); +  if (Field->getType()->isPointerType() && +      Ctx.hasSameType(Field->getType()->getPointeeType(), +                      ArrayType->getElementType())) {      // End pointer. -    llvm::Value *arrayEnd = Builder.CreateStructGEP(alloc,numInits, "arrayend"); -    CGF.EmitStoreThroughLValue(RValue::get(arrayEnd), endOrLength); -  } else if(ctx.hasSameType(field->getType(), ctx.getSizeType())) { +    llvm::Value *IdxEnd[] = { Zero, Size }; +    llvm::Value *ArrayEnd = +        Builder.CreateInBoundsGEP(ArrayPtr, IdxEnd, "arrayend"); +    CGF.EmitStoreThroughLValue(RValue::get(ArrayEnd), EndOrLength); +  } else if (Ctx.hasSameType(Field->getType(), Ctx.getSizeType())) {      // Length. -    CGF.EmitStoreThroughLValue(RValue::get(Builder.getInt(size)), endOrLength); +    CGF.EmitStoreThroughLValue(RValue::get(Size), EndOrLength);    } else { -    CGF.ErrorUnsupported(initList, "weird std::initializer_list"); +    CGF.ErrorUnsupported(E, "weird std::initializer_list");      return;    } - -  if (!Dest.isExternallyDestructed()) -    EmitStdInitializerListCleanup(CGF, array, alloc, initList);  }  /// \brief Emit initialization of an array from an initializer list. @@ -490,15 +430,8 @@ void AggExprEmitter::EmitArrayInit(llvm::Value *DestPtr, llvm::ArrayType *AType,        if (endOfInit) Builder.CreateStore(element, endOfInit);      } -    // If these are nested std::initializer_list inits, do them directly, -    // because they are conceptually the same "location". -    InitListExpr *initList = dyn_cast<InitListExpr>(E->getInit(i)); -    if (initList && initList->initializesStdInitializerList()) { -      EmitStdInitializerList(element, initList); -    } else { -      LValue elementLV = CGF.MakeAddrLValue(element, elementType); -      EmitInitializationToLValue(E->getInit(i), elementLV); -    } +    LValue elementLV = CGF.MakeAddrLValue(element, elementType); +    EmitInitializationToLValue(E->getInit(i), elementLV);    }    // Check whether there's a non-trivial array-fill expression. @@ -679,34 +612,33 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {      }      // If we're converting an r-value of non-atomic type to an r-value -    // of atomic type, just make an atomic temporary, emit into that, -    // and then copy the value out.  (FIXME: do we need to -    // zero-initialize it first?) +    // of atomic type, just emit directly into the relevant sub-object.      if (isToAtomic) { -      ValueDestForAtomic valueDest(CGF, Dest, atomicType); -      CGF.EmitAggExpr(E->getSubExpr(), valueDest.getDest()); +      AggValueSlot valueDest = Dest; +      if (!valueDest.isIgnored() && CGF.CGM.isPaddedAtomicType(atomicType)) { +        // Zero-initialize.  (Strictly speaking, we only need to intialize +        // the padding at the end, but this is simpler.) +        if (!Dest.isZeroed()) +          CGF.EmitNullInitialization(Dest.getAddr(), atomicType); + +        // Build a GEP to refer to the subobject. +        llvm::Value *valueAddr = +            CGF.Builder.CreateStructGEP(valueDest.getAddr(), 0); +        valueDest = AggValueSlot::forAddr(valueAddr, +                                          valueDest.getAlignment(), +                                          valueDest.getQualifiers(), +                                          valueDest.isExternallyDestructed(), +                                          valueDest.requiresGCollection(), +                                          valueDest.isPotentiallyAliased(), +                                          AggValueSlot::IsZeroed); +      } +       +      CGF.EmitAggExpr(E->getSubExpr(), valueDest);        return;      }      // Otherwise, we're converting an atomic type to a non-atomic type. - -    // If the dest is a value-of-atomic subobject, drill back out. -    if (Dest.isValueOfAtomic()) { -      AggValueSlot atomicSlot = -        AggValueSlot::forAddr(Dest.getPaddedAtomicAddr(), -                              Dest.getAlignment(), -                              Dest.getQualifiers(), -                              Dest.isExternallyDestructed(), -                              Dest.requiresGCollection(), -                              Dest.isPotentiallyAliased(), -                              Dest.isZeroed(), -                              AggValueSlot::IsNotValueOfAtomic); -      CGF.EmitAggExpr(E->getSubExpr(), atomicSlot); -      return; -    } - -    // Otherwise, make an atomic temporary, emit into that, and then -    // copy the value out. +    // Make an atomic temporary, emit into that, and then copy the value out.      AggValueSlot atomicSlot =        CGF.CreateAggTemp(atomicType, "atomic-to-nonatomic.temp");      CGF.EmitAggExpr(E->getSubExpr(), atomicSlot); @@ -988,7 +920,7 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {  }  void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) { -  Visit(CE->getChosenSubExpr(CGF.getContext())); +  Visit(CE->getChosenSubExpr());  }  void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) { @@ -1078,7 +1010,7 @@ static bool isSimpleZero(const Expr *E, CodeGenFunction &CGF) {  void  -AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) { +AggExprEmitter::EmitInitializationToLValue(Expr *E, LValue LV) {    QualType type = LV.getType();    // FIXME: Ignore result?    // FIXME: Are initializers affected by volatile? @@ -1088,7 +1020,7 @@ AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) {    } else if (isa<ImplicitValueInitExpr>(E) || isa<CXXScalarValueInitExpr>(E)) {      return EmitNullInitializationToLValue(LV);    } else if (type->isReferenceType()) { -    RValue RV = CGF.EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0); +    RValue RV = CGF.EmitReferenceBindingToExpr(E);      return CGF.EmitStoreThroughLValue(RV, LV);    } @@ -1159,12 +1091,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {    if (E->hadArrayRangeDesignator())      CGF.ErrorUnsupported(E, "GNU array range designator extension"); -  if (E->initializesStdInitializerList()) { -    EmitStdInitializerList(Dest.getAddr(), E); -    return; -  } -    AggValueSlot Dest = EnsureSlot(E->getType()); +    LValue DestLV = CGF.MakeAddrLValue(Dest.getAddr(), E->getType(),                                       Dest.getAlignment()); @@ -1545,58 +1473,3 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,                         alignment.getQuantity(), isVolatile,                         /*TBAATag=*/0, TBAAStructTag);  } - -void CodeGenFunction::MaybeEmitStdInitializerListCleanup(llvm::Value *loc, -                                                         const Expr *init) { -  const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(init); -  if (cleanups) -    init = cleanups->getSubExpr(); - -  if (isa<InitListExpr>(init) && -      cast<InitListExpr>(init)->initializesStdInitializerList()) { -    // We initialized this std::initializer_list with an initializer list. -    // A backing array was created. Push a cleanup for it. -    EmitStdInitializerListCleanup(loc, cast<InitListExpr>(init)); -  } -} - -static void EmitRecursiveStdInitializerListCleanup(CodeGenFunction &CGF, -                                                   llvm::Value *arrayStart, -                                                   const InitListExpr *init) { -  // Check if there are any recursive cleanups to do, i.e. if we have -  //   std::initializer_list<std::initializer_list<obj>> list = {{obj()}}; -  // then we need to destroy the inner array as well. -  for (unsigned i = 0, e = init->getNumInits(); i != e; ++i) { -    const InitListExpr *subInit = dyn_cast<InitListExpr>(init->getInit(i)); -    if (!subInit || !subInit->initializesStdInitializerList()) -      continue; - -    // This one needs to be destroyed. Get the address of the std::init_list. -    llvm::Value *offset = llvm::ConstantInt::get(CGF.SizeTy, i); -    llvm::Value *loc = CGF.Builder.CreateInBoundsGEP(arrayStart, offset, -                                                 "std.initlist"); -    CGF.EmitStdInitializerListCleanup(loc, subInit); -  } -} - -void CodeGenFunction::EmitStdInitializerListCleanup(llvm::Value *loc, -                                                    const InitListExpr *init) { -  ASTContext &ctx = getContext(); -  QualType element = GetStdInitializerListElementType(init->getType()); -  unsigned numInits = init->getNumInits(); -  llvm::APInt size(ctx.getTypeSize(ctx.getSizeType()), numInits); -  QualType array =ctx.getConstantArrayType(element, size, ArrayType::Normal, 0); -  QualType arrayPtr = ctx.getPointerType(array); -  llvm::Type *arrayPtrType = ConvertType(arrayPtr); - -  // lvalue is the location of a std::initializer_list, which as its first -  // element has a pointer to the array we want to destroy. -  llvm::Value *startPointer = Builder.CreateStructGEP(loc, 0, "startPointer"); -  llvm::Value *startAddress = Builder.CreateLoad(startPointer, "startAddress"); - -  ::EmitRecursiveStdInitializerListCleanup(*this, startAddress, init); - -  llvm::Value *arrayAddress = -      Builder.CreateBitCast(startAddress, arrayPtrType, "arrayAddress"); -  ::EmitStdInitializerListCleanup(*this, array, arrayAddress, init); -} diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 83c8ace98cd47..cc7b24d5e83eb 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -16,6 +16,7 @@  #include "CGCXXABI.h"  #include "CGDebugInfo.h"  #include "CGObjCRuntime.h" +#include "clang/CodeGen/CGFunctionInfo.h"  #include "clang/Frontend/CodeGenOptions.h"  #include "llvm/IR/Intrinsics.h"  #include "llvm/Support/CallSite.h" @@ -62,99 +63,6 @@ RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD,                    Callee, ReturnValue, Args, MD);  } -// FIXME: Ideally Expr::IgnoreParenNoopCasts should do this, but it doesn't do -// quite what we want. -static const Expr *skipNoOpCastsAndParens(const Expr *E) { -  while (true) { -    if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) { -      E = PE->getSubExpr(); -      continue; -    } - -    if (const CastExpr *CE = dyn_cast<CastExpr>(E)) { -      if (CE->getCastKind() == CK_NoOp) { -        E = CE->getSubExpr(); -        continue; -      } -    } -    if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { -      if (UO->getOpcode() == UO_Extension) { -        E = UO->getSubExpr(); -        continue; -      } -    } -    return E; -  } -} - -/// canDevirtualizeMemberFunctionCalls - Checks whether virtual calls on given -/// expr can be devirtualized. -static bool canDevirtualizeMemberFunctionCalls(ASTContext &Context, -                                               const Expr *Base,  -                                               const CXXMethodDecl *MD) { -   -  // When building with -fapple-kext, all calls must go through the vtable since -  // the kernel linker can do runtime patching of vtables. -  if (Context.getLangOpts().AppleKext) -    return false; - -  // If the most derived class is marked final, we know that no subclass can -  // override this member function and so we can devirtualize it. For example: -  // -  // struct A { virtual void f(); } -  // struct B final : A { }; -  // -  // void f(B *b) { -  //   b->f(); -  // } -  // -  const CXXRecordDecl *MostDerivedClassDecl = Base->getBestDynamicClassType(); -  if (MostDerivedClassDecl->hasAttr<FinalAttr>()) -    return true; - -  // If the member function is marked 'final', we know that it can't be -  // overridden and can therefore devirtualize it. -  if (MD->hasAttr<FinalAttr>()) -    return true; - -  // Similarly, if the class itself is marked 'final' it can't be overridden -  // and we can therefore devirtualize the member function call. -  if (MD->getParent()->hasAttr<FinalAttr>()) -    return true; - -  Base = skipNoOpCastsAndParens(Base); -  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) { -    if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) { -      // This is a record decl. We know the type and can devirtualize it. -      return VD->getType()->isRecordType(); -    } -     -    return false; -  } - -  // We can devirtualize calls on an object accessed by a class member access -  // expression, since by C++11 [basic.life]p6 we know that it can't refer to -  // a derived class object constructed in the same location. -  if (const MemberExpr *ME = dyn_cast<MemberExpr>(Base)) -    if (const ValueDecl *VD = dyn_cast<ValueDecl>(ME->getMemberDecl())) -      return VD->getType()->isRecordType(); - -  // We can always devirtualize calls on temporary object expressions. -  if (isa<CXXConstructExpr>(Base)) -    return true; -   -  // And calls on bound temporaries. -  if (isa<CXXBindTemporaryExpr>(Base)) -    return true; -   -  // Check if this is a call expr that returns a record type. -  if (const CallExpr *CE = dyn_cast<CallExpr>(Base)) -    return CE->getCallReturnType()->isRecordType(); - -  // We can't devirtualize the call. -  return false; -} -  static CXXRecordDecl *getCXXRecord(const Expr *E) {    QualType T = E->getType();    if (const PointerType *PTy = T->getAs<PointerType>()) @@ -175,22 +83,12 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,    const MemberExpr *ME = cast<MemberExpr>(callee);    const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl()); -  CGDebugInfo *DI = getDebugInfo(); -  if (DI && -      CGM.getCodeGenOpts().getDebugInfo() == CodeGenOptions::LimitedDebugInfo && -      !isa<CallExpr>(ME->getBase())) { -    QualType PQTy = ME->getBase()->IgnoreParenImpCasts()->getType(); -    if (const PointerType * PTy = dyn_cast<PointerType>(PQTy)) { -      DI->getOrCreateRecordType(PTy->getPointeeType(),  -                                MD->getParent()->getLocation()); -    } -  } -    if (MD->isStatic()) {      // The method is static, emit it as we would a regular call.      llvm::Value *Callee = CGM.GetAddrOfFunction(MD);      return EmitCall(getContext().getPointerType(MD->getType()), Callee, -                    ReturnValue, CE->arg_begin(), CE->arg_end()); +                    CE->getLocStart(), ReturnValue, CE->arg_begin(), +                    CE->arg_end());    }    // Compute the object pointer. @@ -198,8 +96,7 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,    bool CanUseVirtualCall = MD->isVirtual() && !ME->hasQualifier();    const CXXMethodDecl *DevirtualizedMethod = NULL; -  if (CanUseVirtualCall && -      canDevirtualizeMemberFunctionCalls(getContext(), Base, MD)) { +  if (CanUseVirtualCall && CanDevirtualizeMemberFunctionCall(Base, MD)) {      const CXXRecordDecl *BestDynamicDecl = Base->getBestDynamicClassType();      DevirtualizedMethod = MD->getCorrespondingMethodInClass(BestDynamicDecl);      assert(DevirtualizedMethod); @@ -271,7 +168,7 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,    else      FInfo = &CGM.getTypes().arrangeCXXMethodDeclaration(CalleeDecl); -  llvm::Type *Ty = CGM.getTypes().GetFunctionType(*FInfo); +  llvm::FunctionType *Ty = CGM.getTypes().GetFunctionType(*FInfo);    // C++ [class.virtual]p12:    //   Explicit qualification with the scope operator (5.1) suppresses the @@ -280,34 +177,37 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,    // We also don't emit a virtual call if the base expression has a record type    // because then we know what the type is.    bool UseVirtualCall = CanUseVirtualCall && !DevirtualizedMethod; -    llvm::Value *Callee; +    if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(MD)) { +    assert(CE->arg_begin() == CE->arg_end() && +           "Destructor shouldn't have explicit parameters"); +    assert(ReturnValue.isNull() && "Destructor shouldn't have return value");      if (UseVirtualCall) { -      assert(CE->arg_begin() == CE->arg_end() && -             "Virtual destructor shouldn't have explicit parameters"); -      return CGM.getCXXABI().EmitVirtualDestructorCall(*this, Dtor, -                                                       Dtor_Complete, -                                                       CE->getExprLoc(), -                                                       ReturnValue, This); +      CGM.getCXXABI().EmitVirtualDestructorCall(*this, Dtor, Dtor_Complete, +                                                CE->getExprLoc(), This);      } else {        if (getLangOpts().AppleKext &&            MD->isVirtual() &&            ME->hasQualifier())          Callee = BuildAppleKextVirtualCall(MD, ME->getQualifier(), Ty);        else if (!DevirtualizedMethod) -        Callee = CGM.GetAddrOfFunction(GlobalDecl(Dtor, Dtor_Complete), Ty); +        Callee = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete, FInfo, Ty);        else {          const CXXDestructorDecl *DDtor =            cast<CXXDestructorDecl>(DevirtualizedMethod);          Callee = CGM.GetAddrOfFunction(GlobalDecl(DDtor, Dtor_Complete), Ty);        } +      EmitCXXMemberCall(MD, CE->getExprLoc(), Callee, ReturnValue, This, +                        /*ImplicitParam=*/0, QualType(), 0, 0);      } -  } else if (const CXXConstructorDecl *Ctor = -               dyn_cast<CXXConstructorDecl>(MD)) { +    return RValue::get(0); +  } +   +  if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {      Callee = CGM.GetAddrOfFunction(GlobalDecl(Ctor, Ctor_Complete), Ty);    } else if (UseVirtualCall) { -      Callee = BuildVirtualCall(MD, This, Ty);  +    Callee = CGM.getCXXABI().getVirtualFunctionPointer(*this, MD, This, Ty);    } else {      if (getLangOpts().AppleKext &&          MD->isVirtual() && @@ -320,6 +220,9 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,      }    } +  if (MD->isVirtual()) +    This = CGM.getCXXABI().adjustThisArgumentForVirtualCall(*this, MD, This); +    return EmitCXXMemberCall(MD, CE->getExprLoc(), Callee, ReturnValue, This,                             /*ImplicitParam=*/0, QualType(),                             CE->arg_begin(), CE->arg_end()); @@ -371,8 +274,8 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,    // And the rest of the call args    EmitCallArgs(Args, FPT, E->arg_begin(), E->arg_end()); -  return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required), Callee,  -                  ReturnValue, Args); +  return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required), +                  Callee, ReturnValue, Args);  }  RValue @@ -540,8 +443,7 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtor(llvm::Value *Dest,    assert(!getContext().getAsConstantArrayType(E->getType())           && "EmitSynthesizedCXXCopyCtor - Copied-in Array"); -  EmitSynthesizedCXXCopyCtorCall(CD, Dest, Src, -                                 E->arg_begin(), E->arg_end()); +  EmitSynthesizedCXXCopyCtorCall(CD, Dest, Src, E->arg_begin(), E->arg_end());  }  static CharUnits CalculateCookiePadding(CodeGenFunction &CGF, @@ -818,7 +720,7 @@ static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF,  static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init,                                      QualType AllocType, llvm::Value *NewPtr) { - +  // FIXME: Refactor with EmitExprAsInit.    CharUnits Alignment = CGF.getContext().getTypeAlignInChars(AllocType);    switch (CGF.getEvaluationKind(AllocType)) {    case TEK_Scalar: @@ -838,8 +740,6 @@ static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init,                                AggValueSlot::DoesNotNeedGCBarriers,                                AggValueSlot::IsNotAliased);      CGF.EmitAggExpr(Init, Slot); - -    CGF.MaybeEmitStdInitializerListCleanup(NewPtr, Init);      return;    }    } @@ -866,10 +766,22 @@ CodeGenFunction::EmitNewArrayInitializer(const CXXNewExpr *E,    QualType::DestructionKind dtorKind = elementType.isDestructedType();    EHScopeStack::stable_iterator cleanup;    llvm::Instruction *cleanupDominator = 0; +    // If the initializer is an initializer list, first do the explicit elements.    if (const InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {      initializerElements = ILE->getNumInits(); +    // If this is a multi-dimensional array new, we will initialize multiple +    // elements with each init list element. +    QualType AllocType = E->getAllocatedType(); +    if (const ConstantArrayType *CAT = dyn_cast_or_null<ConstantArrayType>( +            AllocType->getAsArrayTypeUnsafe())) { +      unsigned AS = explicitPtr->getType()->getPointerAddressSpace(); +      llvm::Type *AllocPtrTy = ConvertTypeForMem(AllocType)->getPointerTo(AS); +      explicitPtr = Builder.CreateBitCast(explicitPtr, AllocPtrTy); +      initializerElements *= getContext().getConstantArrayElementCount(CAT); +    } +      // Enter a partial-destruction cleanup if necessary.      if (needsEHCleanup(dtorKind)) {        // In principle we could tell the cleanup where we are more @@ -888,12 +800,16 @@ CodeGenFunction::EmitNewArrayInitializer(const CXXNewExpr *E,        // element.  TODO: some of these stores can be trivially        // observed to be unnecessary.        if (endOfInit) Builder.CreateStore(explicitPtr, endOfInit); -      StoreAnyExprIntoOneUnit(*this, ILE->getInit(i), elementType, explicitPtr); -      explicitPtr =Builder.CreateConstGEP1_32(explicitPtr, 1, "array.exp.next"); +      StoreAnyExprIntoOneUnit(*this, ILE->getInit(i), +                              ILE->getInit(i)->getType(), explicitPtr); +      explicitPtr = Builder.CreateConstGEP1_32(explicitPtr, 1, +                                               "array.exp.next");      }      // The remaining elements are filled with the array filler expression.      Init = ILE->getArrayFiller(); + +    explicitPtr = Builder.CreateBitCast(explicitPtr, beginPtr->getType());    }    // Create the continuation block. @@ -1012,6 +928,41 @@ static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,    StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr);  } +/// Emit a call to an operator new or operator delete function, as implicitly +/// created by new-expressions and delete-expressions. +static RValue EmitNewDeleteCall(CodeGenFunction &CGF, +                                const FunctionDecl *Callee, +                                const FunctionProtoType *CalleeType, +                                const CallArgList &Args) { +  llvm::Instruction *CallOrInvoke; +  llvm::Value *CalleeAddr = CGF.CGM.GetAddrOfFunction(Callee); +  RValue RV = +      CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(Args, CalleeType), +                   CalleeAddr, ReturnValueSlot(), Args, +                   Callee, &CallOrInvoke); + +  /// C++1y [expr.new]p10: +  ///   [In a new-expression,] an implementation is allowed to omit a call +  ///   to a replaceable global allocation function. +  /// +  /// We model such elidable calls with the 'builtin' attribute. +  llvm::Function *Fn = dyn_cast<llvm::Function>(CalleeAddr); +  if (Callee->isReplaceableGlobalAllocationFunction() && +      Fn && Fn->hasFnAttribute(llvm::Attribute::NoBuiltin)) { +    // FIXME: Add addAttribute to CallSite. +    if (llvm::CallInst *CI = dyn_cast<llvm::CallInst>(CallOrInvoke)) +      CI->addAttribute(llvm::AttributeSet::FunctionIndex, +                       llvm::Attribute::Builtin); +    else if (llvm::InvokeInst *II = dyn_cast<llvm::InvokeInst>(CallOrInvoke)) +      II->addAttribute(llvm::AttributeSet::FunctionIndex, +                       llvm::Attribute::Builtin); +    else +      llvm_unreachable("unexpected kind of call instruction"); +  } + +  return RV; +} +  namespace {    /// A cleanup to call the given 'operator delete' function upon    /// abnormal exit from a new expression. @@ -1061,9 +1012,7 @@ namespace {          DeleteArgs.add(getPlacementArgs()[I], *AI++);        // Call 'operator delete'. -      CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, FPT), -                   CGF.CGM.GetAddrOfFunction(OperatorDelete), -                   ReturnValueSlot(), DeleteArgs, OperatorDelete); +      EmitNewDeleteCall(CGF, OperatorDelete, FPT, DeleteArgs);      }    }; @@ -1122,9 +1071,7 @@ namespace {        }        // Call 'operator delete'. -      CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, FPT), -                   CGF.CGM.GetAddrOfFunction(OperatorDelete), -                   ReturnValueSlot(), DeleteArgs, OperatorDelete); +      EmitNewDeleteCall(CGF, OperatorDelete, FPT, DeleteArgs);      }    };  } @@ -1237,10 +1184,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {      // TODO: kill any unnecessary computations done for the size      // argument.    } else { -    RV = EmitCall(CGM.getTypes().arrangeFreeFunctionCall(allocatorArgs, -                                                         allocatorType), -                  CGM.GetAddrOfFunction(allocator), ReturnValueSlot(), -                  allocatorArgs, allocator); +    RV = EmitNewDeleteCall(*this, allocator, allocatorType, allocatorArgs);    }    // Emit a null check on the allocation result if the allocation @@ -1360,9 +1304,7 @@ void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD,      DeleteArgs.add(RValue::get(Size), SizeTy);    // Emit the call to delete. -  EmitCall(CGM.getTypes().arrangeFreeFunctionCall(DeleteArgs, DeleteFTy), -           CGM.GetAddrOfFunction(DeleteFD), ReturnValueSlot(),  -           DeleteArgs, DeleteFD); +  EmitNewDeleteCall(*this, DeleteFD, DeleteFTy, DeleteArgs);  }  namespace { @@ -1415,8 +1357,7 @@ static void EmitObjectDelete(CodeGenFunction &CGF,          // FIXME: Provide a source location here.          CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;          CGF.CGM.getCXXABI().EmitVirtualDestructorCall(CGF, Dtor, DtorType, -                                                      SourceLocation(), -                                                      ReturnValueSlot(), Ptr); +                                                      SourceLocation(), Ptr);          if (UseGlobalDelete) {            CGF.PopCleanupBlock(); @@ -1519,9 +1460,7 @@ namespace {        }        // Emit the call to delete. -      CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(Args, DeleteFTy), -                   CGF.CGM.GetAddrOfFunction(OperatorDelete), -                   ReturnValueSlot(), Args, OperatorDelete); +      EmitNewDeleteCall(CGF, OperatorDelete, DeleteFTy, Args);      }    };  } @@ -1667,8 +1606,8 @@ llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {      ConvertType(E->getType())->getPointerTo();    if (E->isTypeOperand()) { -    llvm::Constant *TypeInfo =  -      CGM.GetAddrOfRTTIDescriptor(E->getTypeOperand()); +    llvm::Constant *TypeInfo = +        CGM.GetAddrOfRTTIDescriptor(E->getTypeOperand(getContext()));      return Builder.CreateBitCast(TypeInfo, StdTypeInfoPtrTy);    } diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp index 36f974a31329f..73d5bcb13a95a 100644 --- a/lib/CodeGen/CGExprComplex.cpp +++ b/lib/CodeGen/CGExprComplex.cpp @@ -18,6 +18,7 @@  #include "llvm/ADT/SmallString.h"  #include "llvm/IR/Constants.h"  #include "llvm/IR/Function.h" +#include <algorithm>  using namespace clang;  using namespace CodeGen; @@ -69,10 +70,10 @@ public:    /// value l-value, this method emits the address of the l-value, then loads    /// and returns the result.    ComplexPairTy EmitLoadOfLValue(const Expr *E) { -    return EmitLoadOfLValue(CGF.EmitLValue(E)); +    return EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc());    } -  ComplexPairTy EmitLoadOfLValue(LValue LV); +  ComplexPairTy EmitLoadOfLValue(LValue LV, SourceLocation Loc);    /// EmitStoreOfComplex - Store the specified real/imag parts into the    /// specified value pointer. @@ -81,6 +82,9 @@ public:    /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.    ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,                                           QualType DestType); +  /// EmitComplexToComplexCast - Emit a cast from scalar value Val to DestType. +  ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType, +                                        QualType DestType);    //===--------------------------------------------------------------------===//    //                            Visitor Methods @@ -109,11 +113,12 @@ public:    ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) {      if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) {        if (result.isReference()) -        return EmitLoadOfLValue(result.getReferenceLValue(CGF, E)); +        return EmitLoadOfLValue(result.getReferenceLValue(CGF, E), +                                E->getExprLoc()); -      llvm::ConstantStruct *pair = -        cast<llvm::ConstantStruct>(result.getValue()); -      return ComplexPairTy(pair->getOperand(0), pair->getOperand(1)); +      llvm::Constant *pair = result.getValue(); +      return ComplexPairTy(pair->getAggregateElement(0U), +                           pair->getAggregateElement(1U));      }      return EmitLoadOfLValue(E);    } @@ -127,7 +132,7 @@ public:    ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); }    ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) {      if (E->isGLValue()) -      return EmitLoadOfLValue(CGF.getOpaqueLValueMapping(E)); +      return EmitLoadOfLValue(CGF.getOpaqueLValueMapping(E), E->getExprLoc());      return CGF.getOpaqueRValueMapping(E).getComplexVal();    } @@ -215,7 +220,7 @@ public:    LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,                                    ComplexPairTy (ComplexExprEmitter::*Func)                                    (const BinOpInfo &), -                                  ComplexPairTy &Val); +                                  RValue &Val);    ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,                                     ComplexPairTy (ComplexExprEmitter::*Func)                                     (const BinOpInfo &)); @@ -287,26 +292,34 @@ public:  /// EmitLoadOfLValue - Given an RValue reference for a complex, emit code to  /// load the real and imaginary pieces, returning them as Real/Imag. -ComplexPairTy ComplexExprEmitter::EmitLoadOfLValue(LValue lvalue) { +ComplexPairTy ComplexExprEmitter::EmitLoadOfLValue(LValue lvalue, +                                                   SourceLocation loc) {    assert(lvalue.isSimple() && "non-simple complex l-value?");    if (lvalue.getType()->isAtomicType()) -    return CGF.EmitAtomicLoad(lvalue).getComplexVal(); +    return CGF.EmitAtomicLoad(lvalue, loc).getComplexVal();    llvm::Value *SrcPtr = lvalue.getAddress();    bool isVolatile = lvalue.isVolatileQualified(); +  unsigned AlignR = lvalue.getAlignment().getQuantity(); +  ASTContext &C = CGF.getContext(); +  QualType ComplexTy = lvalue.getType(); +  unsigned ComplexAlign = C.getTypeAlignInChars(ComplexTy).getQuantity(); +  unsigned AlignI = std::min(AlignR, ComplexAlign);    llvm::Value *Real=0, *Imag=0;    if (!IgnoreReal || isVolatile) {      llvm::Value *RealP = Builder.CreateStructGEP(SrcPtr, 0,                                                   SrcPtr->getName() + ".realp"); -    Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr->getName() + ".real"); +    Real = Builder.CreateAlignedLoad(RealP, AlignR, isVolatile, +                                     SrcPtr->getName() + ".real");    }    if (!IgnoreImag || isVolatile) {      llvm::Value *ImagP = Builder.CreateStructGEP(SrcPtr, 1,                                                   SrcPtr->getName() + ".imagp"); -    Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr->getName() + ".imag"); +    Imag = Builder.CreateAlignedLoad(ImagP, AlignI, isVolatile, +                                     SrcPtr->getName() + ".imag");    }    return ComplexPairTy(Real, Imag);  } @@ -322,10 +335,16 @@ void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val,    llvm::Value *Ptr = lvalue.getAddress();    llvm::Value *RealPtr = Builder.CreateStructGEP(Ptr, 0, "real");    llvm::Value *ImagPtr = Builder.CreateStructGEP(Ptr, 1, "imag"); - -  // TODO: alignment -  Builder.CreateStore(Val.first, RealPtr, lvalue.isVolatileQualified()); -  Builder.CreateStore(Val.second, ImagPtr, lvalue.isVolatileQualified()); +  unsigned AlignR = lvalue.getAlignment().getQuantity(); +  ASTContext &C = CGF.getContext(); +  QualType ComplexTy = lvalue.getType(); +  unsigned ComplexAlign = C.getTypeAlignInChars(ComplexTy).getQuantity(); +  unsigned AlignI = std::min(AlignR, ComplexAlign); + +  Builder.CreateAlignedStore(Val.first, RealPtr, AlignR, +                             lvalue.isVolatileQualified()); +  Builder.CreateAlignedStore(Val.second, ImagPtr, AlignI, +                             lvalue.isVolatileQualified());  } @@ -358,7 +377,10 @@ ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {  ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {    CodeGenFunction::StmtExprEvaluation eval(CGF); -  return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getComplexVal(); +  llvm::Value *RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), true); +  assert(RetAlloca && "Expected complex return value"); +  return EmitLoadOfLValue(CGF.MakeAddrLValue(RetAlloca, E->getType()), +                          E->getExprLoc());  }  /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType. @@ -377,6 +399,17 @@ ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,    return Val;  } +ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val, +                                                          QualType SrcType, +                                                          QualType DestType) { +  // Convert the input element to the element type of the complex. +  DestType = DestType->castAs<ComplexType>()->getElementType(); +  Val = CGF.EmitScalarConversion(Val, SrcType, DestType); + +  // Return (realval, 0). +  return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType())); +} +  ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op,                                              QualType DestTy) {    switch (CK) { @@ -397,7 +430,8 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op,      V = Builder.CreateBitCast(V,                       CGF.ConvertType(CGF.getContext().getPointerType(DestTy)));      return EmitLoadOfLValue(CGF.MakeAddrLValue(V, DestTy, -                                               origLV.getAlignment())); +                                               origLV.getAlignment()), +                            Op->getExprLoc());    }    case CK_BitCast: @@ -444,16 +478,9 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op,      llvm_unreachable("invalid cast kind for complex value");    case CK_FloatingRealToComplex: -  case CK_IntegralRealToComplex: { -    llvm::Value *Elt = CGF.EmitScalarExpr(Op); - -    // Convert the input element to the element type of the complex. -    DestTy = DestTy->castAs<ComplexType>()->getElementType(); -    Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy); - -    // Return (realval, 0). -    return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType())); -  } +  case CK_IntegralRealToComplex: +    return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op), +                                   Op->getType(), DestTy);    case CK_FloatingComplexCast:    case CK_FloatingComplexToIntegralComplex: @@ -608,7 +635,7 @@ ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) {  LValue ComplexExprEmitter::  EmitCompoundAssignLValue(const CompoundAssignOperator *E,            ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&), -                         ComplexPairTy &Val) { +                         RValue &Val) {    TestAndClearIgnoreReal();    TestAndClearIgnoreImag();    QualType LHSTy = E->getLHS()->getType(); @@ -628,20 +655,29 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,    LValue LHS = CGF.EmitLValue(E->getLHS()); -  // Load from the l-value. -  ComplexPairTy LHSComplexPair = EmitLoadOfLValue(LHS); -   -  OpInfo.LHS = EmitComplexToComplexCast(LHSComplexPair, LHSTy, OpInfo.Ty); +  // Load from the l-value and convert it. +  if (LHSTy->isAnyComplexType()) { +    ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, E->getExprLoc()); +    OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty); +  } else { +    llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, E->getExprLoc()); +    OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty); +  }    // Expand the binary operator.    ComplexPairTy Result = (this->*Func)(OpInfo); -  // Truncate the result back to the LHS type. -  Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy); -  Val = Result; - -  // Store the result value into the LHS lvalue. -  EmitStoreOfComplex(Result, LHS, /*isInit*/ false); +  // Truncate the result and store it into the LHS lvalue. +  if (LHSTy->isAnyComplexType()) { +    ComplexPairTy ResVal = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy); +    EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false); +    Val = RValue::getComplex(ResVal); +  } else { +    llvm::Value *ResVal = +        CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy); +    CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false); +    Val = RValue::get(ResVal); +  }    return LHS;  } @@ -650,18 +686,18 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,  ComplexPairTy ComplexExprEmitter::  EmitCompoundAssign(const CompoundAssignOperator *E,                     ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){ -  ComplexPairTy Val; +  RValue Val;    LValue LV = EmitCompoundAssignLValue(E, Func, Val);    // The result of an assignment in C is the assigned r-value.    if (!CGF.getLangOpts().CPlusPlus) -    return Val; +    return Val.getComplexVal();    // If the lvalue is non-volatile, return the computed value of the assignment.    if (!LV.isVolatileQualified()) -    return Val; +    return Val.getComplexVal(); -  return EmitLoadOfLValue(LV); +  return EmitLoadOfLValue(LV, E->getExprLoc());  }  LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E, @@ -696,7 +732,7 @@ ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {    if (!LV.isVolatileQualified())      return Val; -  return EmitLoadOfLValue(LV); +  return EmitLoadOfLValue(LV, E->getExprLoc());  }  ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { @@ -746,7 +782,7 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {  }  ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) { -  return Visit(E->getChosenSubExpr(CGF.getContext())); +  return Visit(E->getChosenSubExpr());  }  ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) { @@ -785,8 +821,8 @@ ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {      return ComplexPairTy(U, U);    } -  return EmitLoadOfLValue( -               CGF.MakeNaturalAlignAddrLValue(ArgPtr, E->getType())); +  return EmitLoadOfLValue(CGF.MakeNaturalAlignAddrLValue(ArgPtr, E->getType()), +                          E->getExprLoc());  }  //===----------------------------------------------------------------------===// @@ -820,8 +856,9 @@ void CodeGenFunction::EmitStoreOfComplex(ComplexPairTy V, LValue dest,  }  /// EmitLoadOfComplex - Load a complex number from the specified address. -ComplexPairTy CodeGenFunction::EmitLoadOfComplex(LValue src) { -  return ComplexExprEmitter(*this).EmitLoadOfLValue(src); +ComplexPairTy CodeGenFunction::EmitLoadOfComplex(LValue src, +                                                 SourceLocation loc) { +  return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc);  }  LValue CodeGenFunction::EmitComplexAssignmentLValue(const BinaryOperator *E) { @@ -830,19 +867,33 @@ LValue CodeGenFunction::EmitComplexAssignmentLValue(const BinaryOperator *E) {    return ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val);  } -LValue CodeGenFunction:: -EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) { -  ComplexPairTy(ComplexExprEmitter::*Op)(const ComplexExprEmitter::BinOpInfo &); -  switch (E->getOpcode()) { -  case BO_MulAssign: Op = &ComplexExprEmitter::EmitBinMul; break; -  case BO_DivAssign: Op = &ComplexExprEmitter::EmitBinDiv; break; -  case BO_SubAssign: Op = &ComplexExprEmitter::EmitBinSub; break; -  case BO_AddAssign: Op = &ComplexExprEmitter::EmitBinAdd; break; +typedef ComplexPairTy (ComplexExprEmitter::*CompoundFunc)( +    const ComplexExprEmitter::BinOpInfo &); +static CompoundFunc getComplexOp(BinaryOperatorKind Op) { +  switch (Op) { +  case BO_MulAssign: return &ComplexExprEmitter::EmitBinMul; +  case BO_DivAssign: return &ComplexExprEmitter::EmitBinDiv; +  case BO_SubAssign: return &ComplexExprEmitter::EmitBinSub; +  case BO_AddAssign: return &ComplexExprEmitter::EmitBinAdd;    default:      llvm_unreachable("unexpected complex compound assignment");    } +} -  ComplexPairTy Val; // ignored +LValue CodeGenFunction:: +EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) { +  CompoundFunc Op = getComplexOp(E->getOpcode()); +  RValue Val;    return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);  } + +LValue CodeGenFunction:: +EmitScalarCompooundAssignWithComplex(const CompoundAssignOperator *E, +                                     llvm::Value *&Result) { +  CompoundFunc Op = getComplexOp(E->getOpcode()); +  RValue Val; +  LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val); +  Result = Val.getScalarVal(); +  return Ret; +} diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index f5c8187c26f49..f4d6861c8b8bc 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -53,9 +53,6 @@ private:      NextFieldOffsetInChars(CharUnits::Zero()),      LLVMStructAlignment(CharUnits::One()) { } -  void AppendVTablePointer(BaseSubobject Base, llvm::Constant *VTable, -                           const CXXRecordDecl *VTableClass); -    void AppendField(const FieldDecl *Field, uint64_t FieldOffset,                     llvm::Constant *InitExpr); @@ -72,8 +69,7 @@ private:    bool Build(InitListExpr *ILE);    void Build(const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase, -             llvm::Constant *VTable, const CXXRecordDecl *VTableClass, -             CharUnits BaseOffset); +             const CXXRecordDecl *VTableClass, CharUnits BaseOffset);    llvm::Constant *Finalize(QualType Ty);    CharUnits getAlignment(const llvm::Constant *C) const { @@ -88,23 +84,6 @@ private:    }  }; -void ConstStructBuilder::AppendVTablePointer(BaseSubobject Base, -                                             llvm::Constant *VTable, -                                             const CXXRecordDecl *VTableClass) { -  // Find the appropriate vtable within the vtable group. -  uint64_t AddressPoint = -    CGM.getVTableContext().getVTableLayout(VTableClass).getAddressPoint(Base); -  llvm::Value *Indices[] = { -    llvm::ConstantInt::get(CGM.Int64Ty, 0), -    llvm::ConstantInt::get(CGM.Int64Ty, AddressPoint) -  }; -  llvm::Constant *VTableAddressPoint = -    llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Indices); - -  // Add the vtable at the start of the object. -  AppendBytes(Base.getBaseOffset(), VTableAddressPoint); -} -  void ConstStructBuilder::  AppendField(const FieldDecl *Field, uint64_t FieldOffset,              llvm::Constant *InitCst) { @@ -368,40 +347,21 @@ void ConstStructBuilder::ConvertStructToPacked() {  }  bool ConstStructBuilder::Build(InitListExpr *ILE) { -  if (ILE->initializesStdInitializerList()) { -    //CGM.ErrorUnsupported(ILE, "global std::initializer_list"); -    return false; -  } -    RecordDecl *RD = ILE->getType()->getAs<RecordType>()->getDecl();    const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);    unsigned FieldNo = 0;    unsigned ElementNo = 0; -  const FieldDecl *LastFD = 0; -  bool IsMsStruct = RD->isMsStruct(CGM.getContext());    for (RecordDecl::field_iterator Field = RD->field_begin(),         FieldEnd = RD->field_end(); Field != FieldEnd; ++Field, ++FieldNo) { -    if (IsMsStruct) { -      // Zero-length bitfields following non-bitfield members are -      // ignored: -      if (CGM.getContext().ZeroBitfieldFollowsNonBitfield(*Field, LastFD)) { -        --FieldNo; -        continue; -      } -      LastFD = *Field; -    } -          // If this is a union, skip all the fields that aren't being initialized.      if (RD->isUnion() && ILE->getInitializedFieldInUnion() != *Field)        continue;      // Don't emit anonymous bitfields, they just affect layout. -    if (Field->isUnnamedBitfield()) { -      LastFD = *Field; +    if (Field->isUnnamedBitfield())        continue; -    }      // Get the initializer.  A struct can include fields without initializers,      // we just use explicit null values for them. @@ -443,15 +403,19 @@ struct BaseInfo {  }  void ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD, -                               bool IsPrimaryBase, llvm::Constant *VTable, +                               bool IsPrimaryBase,                                 const CXXRecordDecl *VTableClass,                                 CharUnits Offset) {    const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);    if (const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {      // Add a vtable pointer, if we need one and it hasn't already been added. -    if (CD->isDynamicClass() && !IsPrimaryBase) -      AppendVTablePointer(BaseSubobject(CD, Offset), VTable, VTableClass); +    if (CD->isDynamicClass() && !IsPrimaryBase) { +      llvm::Constant *VTableAddressPoint = +          CGM.getCXXABI().getVTableAddressPointForConstExpr( +              BaseSubobject(CD, Offset), VTableClass); +      AppendBytes(Offset, VTableAddressPoint); +    }      // Accumulate and sort bases, in order to visit them in address order, which      // may not be the same as declaration order. @@ -472,36 +436,22 @@ void ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,        bool IsPrimaryBase = Layout.getPrimaryBase() == Base.Decl;        Build(Val.getStructBase(Base.Index), Base.Decl, IsPrimaryBase, -            VTable, VTableClass, Offset + Base.Offset); +            VTableClass, Offset + Base.Offset);      }    }    unsigned FieldNo = 0; -  const FieldDecl *LastFD = 0; -  bool IsMsStruct = RD->isMsStruct(CGM.getContext());    uint64_t OffsetBits = CGM.getContext().toBits(Offset);    for (RecordDecl::field_iterator Field = RD->field_begin(),         FieldEnd = RD->field_end(); Field != FieldEnd; ++Field, ++FieldNo) { -    if (IsMsStruct) { -      // Zero-length bitfields following non-bitfield members are -      // ignored: -      if (CGM.getContext().ZeroBitfieldFollowsNonBitfield(*Field, LastFD)) { -        --FieldNo; -        continue; -      } -      LastFD = *Field; -    } -      // If this is a union, skip all the fields that aren't being initialized.      if (RD->isUnion() && Val.getUnionField() != *Field)        continue;      // Don't emit anonymous bitfields, they just affect layout. -    if (Field->isUnnamedBitfield()) { -      LastFD = *Field; +    if (Field->isUnnamedBitfield())        continue; -    }      // Emit the value of the initializer.      const APValue &FieldValue = @@ -593,11 +543,7 @@ llvm::Constant *ConstStructBuilder::BuildStruct(CodeGenModule &CGM,    const RecordDecl *RD = ValTy->castAs<RecordType>()->getDecl();    const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD); -  llvm::Constant *VTable = 0; -  if (CD && CD->isDynamicClass()) -    VTable = CGM.getVTables().GetAddrOfVTable(CD); - -  Builder.Build(Val, RD, false, VTable, CD, CharUnits::Zero()); +  Builder.Build(Val, RD, false, CD, CharUnits::Zero());    return Builder.Finalize(ValTy);  } @@ -642,6 +588,10 @@ public:      return Visit(GE->getResultExpr());    } +  llvm::Constant *VisitChooseExpr(ChooseExpr *CE) { +    return Visit(CE->getChosenSubExpr()); +  } +    llvm::Constant *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {      return Visit(E->getInitializer());    } @@ -687,6 +637,7 @@ public:      case CK_AtomicToNonAtomic:      case CK_NonAtomicToAtomic:      case CK_NoOp: +    case CK_ConstructorConversion:        return C;      case CK_Dependent: llvm_unreachable("saw dependent cast!"); @@ -716,7 +667,6 @@ public:      case CK_LValueBitCast:      case CK_NullToMemberPointer:      case CK_UserDefinedConversion: -    case CK_ConstructorConversion:      case CK_CPointerToObjCPointerCast:      case CK_BlockPointerToObjCPointerCast:      case CK_AnyPointerToBlockPointerCast: @@ -995,7 +945,7 @@ public:        CXXTypeidExpr *Typeid = cast<CXXTypeidExpr>(E);        QualType T;        if (Typeid->isTypeOperand()) -        T = Typeid->getTypeOperand(); +        T = Typeid->getTypeOperand(CGM.getContext());        else          T = Typeid->getExprOperand()->getType();        return CGM.GetAddrOfRTTIDescriptor(T); @@ -1003,6 +953,15 @@ public:      case Expr::CXXUuidofExprClass: {        return CGM.GetAddrOfUuidDescriptor(cast<CXXUuidofExpr>(E));      } +    case Expr::MaterializeTemporaryExprClass: { +      MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(E); +      assert(MTE->getStorageDuration() == SD_Static); +      SmallVector<const Expr *, 2> CommaLHSs; +      SmallVector<SubobjectAdjustment, 2> Adjustments; +      const Expr *Inner = MTE->GetTemporaryExpr() +          ->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments); +      return CGM.GetAddrOfGlobalTemporary(MTE, Inner); +    }      }      return 0; diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index c1c252d12b76b..f3a5387c58d3c 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -87,15 +87,16 @@ public:    void EmitBinOpCheck(Value *Check, const BinOpInfo &Info); -  Value *EmitLoadOfLValue(LValue LV) { -    return CGF.EmitLoadOfLValue(LV).getScalarVal(); +  Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) { +    return CGF.EmitLoadOfLValue(LV, Loc).getScalarVal();    }    /// EmitLoadOfLValue - Given an expression with complex type that represents a    /// value l-value, this method emits the address of the l-value, then loads    /// and returns the result.    Value *EmitLoadOfLValue(const Expr *E) { -    return EmitLoadOfLValue(EmitCheckedLValue(E, CodeGenFunction::TCK_Load)); +    return EmitLoadOfLValue(EmitCheckedLValue(E, CodeGenFunction::TCK_Load), +                            E->getExprLoc());    }    /// EmitConversionToBool - Convert the specified expression value to a @@ -161,18 +162,18 @@ public:    Value *Visit(Expr *E) {      return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);    } -     +    Value *VisitStmt(Stmt *S) {      S->dump(CGF.getContext().getSourceManager());      llvm_unreachable("Stmt can't have complex result type!");    }    Value *VisitExpr(Expr *S); -   +    Value *VisitParenExpr(ParenExpr *PE) { -    return Visit(PE->getSubExpr());  +    return Visit(PE->getSubExpr());    }    Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) { -    return Visit(E->getReplacement());  +    return Visit(E->getReplacement());    }    Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {      return Visit(GE->getResultExpr()); @@ -217,7 +218,7 @@ public:    Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {      if (E->isGLValue()) -      return EmitLoadOfLValue(CGF.getOpaqueLValueMapping(E)); +      return EmitLoadOfLValue(CGF.getOpaqueLValueMapping(E), E->getExprLoc());      // Otherwise, assume the mapping is the scalar directly.      return CGF.getOpaqueRValueMapping(E).getScalarVal(); @@ -227,7 +228,8 @@ public:    Value *VisitDeclRefExpr(DeclRefExpr *E) {      if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) {        if (result.isReference()) -        return EmitLoadOfLValue(result.getReferenceLValue(CGF, E)); +        return EmitLoadOfLValue(result.getReferenceLValue(CGF, E), +                                E->getExprLoc());        return result.getValue();      }      return EmitLoadOfLValue(E); @@ -243,7 +245,7 @@ public:      return EmitLoadOfLValue(E);    }    Value *VisitObjCMessageExpr(ObjCMessageExpr *E) { -    if (E->getMethodDecl() &&  +    if (E->getMethodDecl() &&          E->getMethodDecl()->getResultType()->isReferenceType())        return EmitLoadOfLValue(E);      return CGF.EmitObjCMessageExpr(E).getScalarVal(); @@ -251,12 +253,13 @@ public:    Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {      LValue LV = CGF.EmitObjCIsaExpr(E); -    Value *V = CGF.EmitLoadOfLValue(LV).getScalarVal(); +    Value *V = CGF.EmitLoadOfLValue(LV, E->getExprLoc()).getScalarVal();      return V;    }    Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);    Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E); +  Value *VisitConvertVectorExpr(ConvertVectorExpr *E);    Value *VisitMemberExpr(MemberExpr *E);    Value *VisitExtVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }    Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { @@ -310,7 +313,7 @@ public:    llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,                                         bool isInc, bool isPre); -     +    Value *VisitUnaryAddrOf(const UnaryOperator *E) {      if (isa<MemberPointerType>(E->getType())) // never sugared        return CGF.CGM.getMemberPointerConstant(E); @@ -335,12 +338,12 @@ public:    Value *VisitUnaryExtension(const UnaryOperator *E) {      return Visit(E->getSubExpr());    } -     +    // C++    Value *VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E) {      return EmitLoadOfLValue(E);    } -     +    Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {      return Visit(DAE->getExpr());    } @@ -430,7 +433,7 @@ public:    Value *EmitOverflowCheckedBinOp(const BinOpInfo &Ops);    // Check for undefined division and modulus behaviors. -  void EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo &Ops,  +  void EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo &Ops,                                                    llvm::Value *Zero,bool isDiv);    // Common helper for getting how wide LHS of shift is.    static Value *GetWidthMinusOneValue(Value* LHS,Value* RHS); @@ -893,51 +896,43 @@ Value *ScalarExprEmitter::VisitExpr(Expr *E) {  Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {    // Vector Mask Case -  if (E->getNumSubExprs() == 2 ||  +  if (E->getNumSubExprs() == 2 ||        (E->getNumSubExprs() == 3 && E->getExpr(2)->getType()->isVectorType())) {      Value *LHS = CGF.EmitScalarExpr(E->getExpr(0));      Value *RHS = CGF.EmitScalarExpr(E->getExpr(1));      Value *Mask; -     +      llvm::VectorType *LTy = cast<llvm::VectorType>(LHS->getType());      unsigned LHSElts = LTy->getNumElements();      if (E->getNumSubExprs() == 3) {        Mask = CGF.EmitScalarExpr(E->getExpr(2)); -       +        // Shuffle LHS & RHS into one input vector.        SmallVector<llvm::Constant*, 32> concat;        for (unsigned i = 0; i != LHSElts; ++i) {          concat.push_back(Builder.getInt32(2*i));          concat.push_back(Builder.getInt32(2*i+1));        } -       +        Value* CV = llvm::ConstantVector::get(concat);        LHS = Builder.CreateShuffleVector(LHS, RHS, CV, "concat");        LHSElts *= 2;      } else {        Mask = RHS;      } -     +      llvm::VectorType *MTy = cast<llvm::VectorType>(Mask->getType());      llvm::Constant* EltMask; -     -    // Treat vec3 like vec4. -    if ((LHSElts == 6) && (E->getNumSubExprs() == 3)) -      EltMask = llvm::ConstantInt::get(MTy->getElementType(), -                                       (1 << llvm::Log2_32(LHSElts+2))-1); -    else if ((LHSElts == 3) && (E->getNumSubExprs() == 2)) -      EltMask = llvm::ConstantInt::get(MTy->getElementType(), -                                       (1 << llvm::Log2_32(LHSElts+1))-1); -    else -      EltMask = llvm::ConstantInt::get(MTy->getElementType(), -                                       (1 << llvm::Log2_32(LHSElts))-1); -              + +    EltMask = llvm::ConstantInt::get(MTy->getElementType(), +                                     llvm::NextPowerOf2(LHSElts-1)-1); +      // Mask off the high bits of each shuffle index.      Value *MaskBits = llvm::ConstantVector::getSplat(MTy->getNumElements(),                                                       EltMask);      Mask = Builder.CreateAnd(Mask, MaskBits, "mask"); -     +      // newv = undef      // mask = mask & maskbits      // for each elt @@ -945,43 +940,110 @@ Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {      //   x = extract val n      //   newv = insert newv, x, i      llvm::VectorType *RTy = llvm::VectorType::get(LTy->getElementType(), -                                                        MTy->getNumElements()); +                                                  MTy->getNumElements());      Value* NewV = llvm::UndefValue::get(RTy);      for (unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {        Value *IIndx = Builder.getInt32(i);        Value *Indx = Builder.CreateExtractElement(Mask, IIndx, "shuf_idx");        Indx = Builder.CreateZExt(Indx, CGF.Int32Ty, "idx_zext"); -       -      // Handle vec3 special since the index will be off by one for the RHS. -      if ((LHSElts == 6) && (E->getNumSubExprs() == 3)) { -        Value *cmpIndx, *newIndx; -        cmpIndx = Builder.CreateICmpUGT(Indx, Builder.getInt32(3), -                                        "cmp_shuf_idx"); -        newIndx = Builder.CreateSub(Indx, Builder.getInt32(1), "shuf_idx_adj"); -        Indx = Builder.CreateSelect(cmpIndx, newIndx, Indx, "sel_shuf_idx"); -      } +        Value *VExt = Builder.CreateExtractElement(LHS, Indx, "shuf_elt");        NewV = Builder.CreateInsertElement(NewV, VExt, IIndx, "shuf_ins");      }      return NewV;    } -   +    Value* V1 = CGF.EmitScalarExpr(E->getExpr(0));    Value* V2 = CGF.EmitScalarExpr(E->getExpr(1)); -   -  // Handle vec3 special since the index will be off by one for the RHS. -  llvm::VectorType *VTy = cast<llvm::VectorType>(V1->getType()); +    SmallVector<llvm::Constant*, 32> indices; -  for (unsigned i = 2; i < E->getNumSubExprs(); i++) { -    unsigned Idx = E->getShuffleMaskIdx(CGF.getContext(), i-2); -    if (VTy->getNumElements() == 3 && Idx > 3) -      Idx -= 1; -    indices.push_back(Builder.getInt32(Idx)); +  for (unsigned i = 2; i < E->getNumSubExprs(); ++i) { +    llvm::APSInt Idx = E->getShuffleMaskIdx(CGF.getContext(), i-2); +    // Check for -1 and output it as undef in the IR. +    if (Idx.isSigned() && Idx.isAllOnesValue()) +      indices.push_back(llvm::UndefValue::get(CGF.Int32Ty)); +    else +      indices.push_back(Builder.getInt32(Idx.getZExtValue()));    }    Value *SV = llvm::ConstantVector::get(indices);    return Builder.CreateShuffleVector(V1, V2, SV, "shuffle");  } + +Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) { +  QualType SrcType = E->getSrcExpr()->getType(), +           DstType = E->getType(); + +  Value *Src  = CGF.EmitScalarExpr(E->getSrcExpr()); + +  SrcType = CGF.getContext().getCanonicalType(SrcType); +  DstType = CGF.getContext().getCanonicalType(DstType); +  if (SrcType == DstType) return Src; + +  assert(SrcType->isVectorType() && +         "ConvertVector source type must be a vector"); +  assert(DstType->isVectorType() && +         "ConvertVector destination type must be a vector"); + +  llvm::Type *SrcTy = Src->getType(); +  llvm::Type *DstTy = ConvertType(DstType); + +  // Ignore conversions like int -> uint. +  if (SrcTy == DstTy) +    return Src; + +  QualType SrcEltType = SrcType->getAs<VectorType>()->getElementType(), +           DstEltType = DstType->getAs<VectorType>()->getElementType(); + +  assert(SrcTy->isVectorTy() && +         "ConvertVector source IR type must be a vector"); +  assert(DstTy->isVectorTy() && +         "ConvertVector destination IR type must be a vector"); + +  llvm::Type *SrcEltTy = SrcTy->getVectorElementType(), +             *DstEltTy = DstTy->getVectorElementType(); + +  if (DstEltType->isBooleanType()) { +    assert((SrcEltTy->isFloatingPointTy() || +            isa<llvm::IntegerType>(SrcEltTy)) && "Unknown boolean conversion"); + +    llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy); +    if (SrcEltTy->isFloatingPointTy()) { +      return Builder.CreateFCmpUNE(Src, Zero, "tobool"); +    } else { +      return Builder.CreateICmpNE(Src, Zero, "tobool"); +    } +  } + +  // We have the arithmetic types: real int/float. +  Value *Res = NULL; + +  if (isa<llvm::IntegerType>(SrcEltTy)) { +    bool InputSigned = SrcEltType->isSignedIntegerOrEnumerationType(); +    if (isa<llvm::IntegerType>(DstEltTy)) +      Res = Builder.CreateIntCast(Src, DstTy, InputSigned, "conv"); +    else if (InputSigned) +      Res = Builder.CreateSIToFP(Src, DstTy, "conv"); +    else +      Res = Builder.CreateUIToFP(Src, DstTy, "conv"); +  } else if (isa<llvm::IntegerType>(DstEltTy)) { +    assert(SrcEltTy->isFloatingPointTy() && "Unknown real conversion"); +    if (DstEltType->isSignedIntegerOrEnumerationType()) +      Res = Builder.CreateFPToSI(Src, DstTy, "conv"); +    else +      Res = Builder.CreateFPToUI(Src, DstTy, "conv"); +  } else { +    assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() && +           "Unknown real conversion"); +    if (DstEltTy->getTypeID() < SrcEltTy->getTypeID()) +      Res = Builder.CreateFPTrunc(Src, DstTy, "conv"); +    else +      Res = Builder.CreateFPExt(Src, DstTy, "conv"); +  } + +  return Res; +} +  Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {    llvm::APSInt Value;    if (E->EvaluateAsInt(Value, CGF.getContext(), Expr::SE_AllowSideEffects)) { @@ -992,18 +1054,6 @@ Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {      return Builder.getInt(Value);    } -  // Emit debug info for aggregate now, if it was delayed to reduce -  // debug info size. -  CGDebugInfo *DI = CGF.getDebugInfo(); -  if (DI && -      CGF.CGM.getCodeGenOpts().getDebugInfo() -        == CodeGenOptions::LimitedDebugInfo) { -    QualType PQTy = E->getBase()->IgnoreParenImpCasts()->getType(); -    if (const PointerType * PTy = dyn_cast<PointerType>(PQTy)) -      if (FieldDecl *M = dyn_cast<FieldDecl>(E->getMemberDecl())) -        DI->getOrCreateRecordType(PTy->getPointeeType(), -                                  M->getParent()->getLocation()); -  }    return EmitLoadOfLValue(E);  } @@ -1023,7 +1073,7 @@ Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {    Value *Idx  = Visit(E->getIdx());    QualType IdxTy = E->getIdx()->getType(); -  if (CGF.SanOpts->Bounds) +  if (CGF.SanOpts->ArrayBounds)      CGF.EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, /*Accessed*/true);    bool IdxSigned = IdxTy->isSignedIntegerOrEnumerationType(); @@ -1034,7 +1084,7 @@ Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {  static llvm::Constant *getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx,                                    unsigned Off, llvm::Type *I32Ty) {    int MV = SVI->getMaskValue(Idx); -  if (MV == -1)  +  if (MV == -1)      return llvm::UndefValue::get(I32Ty);    return llvm::ConstantInt::get(I32Ty, Off+MV);  } @@ -1044,13 +1094,13 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {    (void)Ignore;    assert (Ignore == false && "init list ignored");    unsigned NumInitElements = E->getNumInits(); -   +    if (E->hadArrayRangeDesignator())      CGF.ErrorUnsupported(E, "GNU array range designator extension"); -   +    llvm::VectorType *VType =      dyn_cast<llvm::VectorType>(ConvertType(E->getType())); -   +    if (!VType) {      if (NumInitElements == 0) {        // C++11 value-initialization for the scalar. @@ -1059,10 +1109,10 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {      // We have a scalar in braces. Just use the first element.      return Visit(E->getInit(0));    } -   +    unsigned ResElts = VType->getNumElements(); -   -  // Loop over initializers collecting the Value for each, and remembering  + +  // Loop over initializers collecting the Value for each, and remembering    // whether the source was swizzle (ExtVectorElementExpr).  This will allow    // us to fold the shuffle for the swizzle into the shuffle for the vector    // initializer, since LLVM optimizers generally do not want to touch @@ -1074,11 +1124,11 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {      Expr *IE = E->getInit(i);      Value *Init = Visit(IE);      SmallVector<llvm::Constant*, 16> Args; -     +      llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType()); -     +      // Handle scalar elements.  If the scalar initializer is actually one -    // element of a different vector of the same width, use shuffle instead of  +    // element of a different vector of the same width, use shuffle instead of      // extract+insert.      if (!VVT) {        if (isa<ExtVectorElementExpr>(IE)) { @@ -1121,10 +1171,10 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {        ++CurIdx;        continue;      } -     +      unsigned InitElts = VVT->getNumElements(); -    // If the initializer is an ExtVecEltExpr (a swizzle), and the swizzle's  +    // If the initializer is an ExtVecEltExpr (a swizzle), and the swizzle's      // input is the same width as the vector being constructed, generate an      // optimized shuffle of the swizzle input into the result.      unsigned Offset = (CurIdx == 0) ? 0 : ResElts; @@ -1132,7 +1182,7 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {        llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init);        Value *SVOp = SVI->getOperand(0);        llvm::VectorType *OpTy = cast<llvm::VectorType>(SVOp->getType()); -       +        if (OpTy->getNumElements() == ResElts) {          for (unsigned j = 0; j != CurIdx; ++j) {            // If the current vector initializer is a shuffle with undef, merge @@ -1182,11 +1232,11 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {      VIsUndefShuffle = isa<llvm::UndefValue>(Init);      CurIdx += InitElts;    } -   +    // FIXME: evaluate codegen vs. shuffling against constant null vector.    // Emit remaining default initializers.    llvm::Type *EltTy = VType->getElementType(); -   +    // Emit remaining default initializers    for (/* Do not initialize i*/; CurIdx < ResElts; ++CurIdx) {      Value *Idx = Builder.getInt32(CurIdx); @@ -1201,12 +1251,12 @@ static bool ShouldNullCheckClassCastValue(const CastExpr *CE) {    if (CE->getCastKind() == CK_UncheckedDerivedToBase)      return false; -   +    if (isa<CXXThisExpr>(E)) {      // We always assume that 'this' is never null.      return false;    } -   +    if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(CE)) {      // And that glvalue casts are never null.      if (ICE->getValueKind() != VK_RValue) @@ -1223,7 +1273,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {    Expr *E = CE->getSubExpr();    QualType DestTy = CE->getType();    CastKind Kind = CE->getCastKind(); -   +    if (!DestTy->isVoidType())      TestAndClearIgnoreResultAssign(); @@ -1235,12 +1285,13 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {    case CK_BuiltinFnToFnPtr:      llvm_unreachable("builtin functions are handled elsewhere"); -  case CK_LValueBitCast:  +  case CK_LValueBitCast:    case CK_ObjCObjectLValueCast: {      Value *V = EmitLValue(E).getAddress(); -    V = Builder.CreateBitCast(V,  +    V = Builder.CreateBitCast(V,                            ConvertType(CGF.getContext().getPointerType(DestTy))); -    return EmitLoadOfLValue(CGF.MakeNaturalAlignAddrLValue(V, DestTy)); +    return EmitLoadOfLValue(CGF.MakeNaturalAlignAddrLValue(V, DestTy), +                            CE->getExprLoc());    }    case CK_CPointerToObjCPointerCast: @@ -1262,15 +1313,18 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {      llvm::Value *V = Visit(E); +    llvm::Value *Derived = +      CGF.GetAddressOfDerivedClass(V, DerivedClassDecl, +                                   CE->path_begin(), CE->path_end(), +                                   ShouldNullCheckClassCastValue(CE)); +      // C++11 [expr.static.cast]p11: Behavior is undefined if a downcast is      // performed and the object is not of the derived type.      if (CGF.SanitizePerformTypeCheck)        CGF.EmitTypeCheck(CodeGenFunction::TCK_DowncastPointer, CE->getExprLoc(), -                        V, DestTy->getPointeeType()); +                        Derived, DestTy->getPointeeType()); -    return CGF.GetAddressOfDerivedClass(V, DerivedClassDecl, -                                        CE->path_begin(), CE->path_end(), -                                        ShouldNullCheckClassCastValue(CE)); +    return Derived;    }    case CK_UncheckedDerivedToBase:    case CK_DerivedToBase: { @@ -1278,7 +1332,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {        E->getType()->getPointeeCXXRecordDecl();      assert(DerivedClassDecl && "DerivedToBase arg isn't a C++ object pointer!"); -    return CGF.GetAddressOfBaseClass(Visit(E), DerivedClassDecl,  +    return CGF.GetAddressOfBaseClass(Visit(E), DerivedClassDecl,                                       CE->path_begin(), CE->path_end(),                                       ShouldNullCheckClassCastValue(CE));    } @@ -1330,7 +1384,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {    case CK_BaseToDerivedMemberPointer:    case CK_DerivedToBaseMemberPointer: {      Value *Src = Visit(E); -     +      // Note that the AST doesn't distinguish between checked and      // unchecked member pointer conversions, so we always have to      // implement checked conversions here.  This is inefficient when @@ -1354,7 +1408,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {    case CK_CopyAndAutoreleaseBlockObject:      return CGF.EmitBlockCopyAndAutorelease(Visit(E), E->getType()); -       +    case CK_FloatingRealToComplex:    case CK_FloatingComplexCast:    case CK_IntegralRealToComplex: @@ -1442,8 +1496,12 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {  Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) {    CodeGenFunction::StmtExprEvaluation eval(CGF); -  return CGF.EmitCompoundStmt(*E->getSubStmt(), !E->getType()->isVoidType()) -    .getScalarVal(); +  llvm::Value *RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), +                                                !E->getType()->isVoidType()); +  if (!RetAlloca) +    return 0; +  return CGF.EmitLoadOfScalar(CGF.MakeAddrLValue(RetAlloca, E->getType()), +                              E->getExprLoc());  }  //===----------------------------------------------------------------------===// @@ -1477,7 +1535,7 @@ EmitAddConsiderOverflowBehavior(const UnaryOperator *E,  llvm::Value *  ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,                                             bool isInc, bool isPre) { -   +    QualType type = E->getSubExpr()->getType();    llvm::PHINode *atomicPHI = 0;    llvm::Value *value; @@ -1503,7 +1561,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,      }      // Special case for atomic increment / decrement on integers, emit      // atomicrmw instructions.  We skip this if we want to be doing overflow -    // checking, and fall into the slow path with the atomic cmpxchg loop.   +    // checking, and fall into the slow path with the atomic cmpxchg loop.      if (!type->isBooleanType() && type->isIntegerType() &&          !(type->isUnsignedIntegerType() &&           CGF.SanOpts->UnsignedIntegerOverflow) && @@ -1519,7 +1577,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,            LV.getAddress(), amt, llvm::SequentiallyConsistent);        return isPre ? Builder.CreateBinOp(op, old, amt) : old;      } -    value = EmitLoadOfLValue(LV); +    value = EmitLoadOfLValue(LV, E->getExprLoc());      input = value;      // For every other atomic operation, we need to emit a load-op-cmpxchg loop      llvm::BasicBlock *startBB = Builder.GetInsertBlock(); @@ -1531,7 +1589,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,      atomicPHI->addIncoming(value, startBB);      value = atomicPHI;    } else { -    value = EmitLoadOfLValue(LV); +    value = EmitLoadOfLValue(LV, E->getExprLoc());      input = value;    } @@ -1569,7 +1627,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,        value = EmitOverflowCheckedBinOp(BinOp);      } else        value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec"); -   +    // Next most common: pointer increment.    } else if (const PointerType *ptr = type->getAs<PointerType>()) {      QualType type = ptr->getPointeeType(); @@ -1583,7 +1641,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,          value = Builder.CreateGEP(value, numElts, "vla.inc");        else          value = Builder.CreateInBoundsGEP(value, numElts, "vla.inc"); -     +      // Arithmetic on function pointers (!) is just +-1.      } else if (type->isFunctionType()) {        llvm::Value *amt = Builder.getInt32(amount); @@ -1665,7 +1723,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,        value = Builder.CreateInBoundsGEP(value, sizeValue, "incdec.objptr");      value = Builder.CreateBitCast(value, input->getType());    } -   +    if (atomicPHI) {      llvm::BasicBlock *opBB = Builder.GetInsertBlock();      llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn); @@ -1696,10 +1754,10 @@ Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {    // Emit unary minus with EmitSub so we handle overflow cases etc.    BinOpInfo BinOp;    BinOp.RHS = Visit(E->getSubExpr()); -   +    if (BinOp.RHS->getType()->isFPOrFPVectorTy())      BinOp.LHS = llvm::ConstantFP::getZeroValueForNegation(BinOp.RHS->getType()); -  else  +  else      BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());    BinOp.Ty = E->getType();    BinOp.Opcode = BO_Sub; @@ -1726,7 +1784,7 @@ Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {        Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp");      return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext");    } -   +    // Compare operand to zero.    Value *BoolVal = CGF.EvaluateExprAsBool(E->getSubExpr()); @@ -1814,7 +1872,7 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {        // Save the element type.        CurrentType = ON.getBase()->getType(); -       +        // Compute the offset to the base.        const RecordType *BaseRT = CurrentType->getAs<RecordType>();        CXXRecordDecl *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl()); @@ -1873,7 +1931,8 @@ Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E) {      // Note that we have to ask E because Op might be an l-value that      // this won't work for, e.g. an Obj-C property.      if (E->isGLValue()) -      return CGF.EmitLoadOfLValue(CGF.EmitLValue(E)).getScalarVal(); +      return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), +                                  E->getExprLoc()).getScalarVal();      // Otherwise, calculate and project.      return CGF.EmitComplexExpr(Op, false, true).first; @@ -1889,7 +1948,8 @@ Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) {      // Note that we have to ask E because Op might be an l-value that      // this won't work for, e.g. an Obj-C property.      if (Op->isGLValue()) -      return CGF.EmitLoadOfLValue(CGF.EmitLValue(E)).getScalarVal(); +      return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), +                                  E->getExprLoc()).getScalarVal();      // Otherwise, calculate and project.      return CGF.EmitComplexExpr(Op, true, false).second; @@ -1926,17 +1986,10 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue(                                                     Value *&Result) {    QualType LHSTy = E->getLHS()->getType();    BinOpInfo OpInfo; -   -  if (E->getComputationResultType()->isAnyComplexType()) { -    // This needs to go through the complex expression emitter, but it's a tad -    // complicated to do that... I'm leaving it out for now.  (Note that we do -    // actually need the imaginary part of the RHS for multiplication and -    // division.) -    CGF.ErrorUnsupported(E, "complex compound assignment"); -    Result = llvm::UndefValue::get(CGF.ConvertType(E->getType())); -    return LValue(); -  } -   + +  if (E->getComputationResultType()->isAnyComplexType()) +    return CGF.EmitScalarCompooundAssignWithComplex(E, Result); +    // Emit the RHS first.  __block variables need to have the rhs evaluated    // first, plus this should improve codegen a little.    OpInfo.RHS = Visit(E->getRHS()); @@ -1993,7 +2046,7 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue(      // floating point environment in the loop.      llvm::BasicBlock *startBB = Builder.GetInsertBlock();      llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn); -    OpInfo.LHS = EmitLoadOfLValue(LHSLV); +    OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc());      OpInfo.LHS = CGF.EmitToMemory(OpInfo.LHS, type);      Builder.CreateBr(opBB);      Builder.SetInsertPoint(opBB); @@ -2002,14 +2055,14 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue(      OpInfo.LHS = atomicPHI;    }    else -    OpInfo.LHS = EmitLoadOfLValue(LHSLV); +    OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc());    OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,                                      E->getComputationLHSType());    // Expand the binary operator.    Result = (this->*Func)(OpInfo); -   +    // Convert the result back to the LHS type.    Result = EmitScalarConversion(Result, E->getComputationResultType(), LHSTy); @@ -2024,7 +2077,7 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue(      Builder.SetInsertPoint(contBB);      return LHSLV;    } -   +    // Store the result value into the LHS lvalue. Bit-fields are handled    // specially because the result is altered by the store, i.e., [C99 6.5.16p1]    // 'An assignment expression has the value of the left operand after the @@ -2056,7 +2109,7 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,      return RHS;    // Otherwise, reload the value. -  return EmitLoadOfLValue(LHS); +  return EmitLoadOfLValue(LHS, E->getExprLoc());  }  void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck( @@ -2236,7 +2289,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,    // Must have binary (not unary) expr here.  Unary pointer    // increment/decrement doesn't use this path.    const BinaryOperator *expr = cast<BinaryOperator>(op.E); -   +    Value *pointer = op.LHS;    Expr *pointerOperand = expr->getLHS();    Value *index = op.RHS; @@ -2261,7 +2314,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,    if (isSubtraction)      index = CGF.Builder.CreateNeg(index, "idx.neg"); -  if (CGF.SanOpts->Bounds) +  if (CGF.SanOpts->ArrayBounds)      CGF.EmitBoundsCheck(op.E, pointerOperand, index, indexOperand->getType(),                          /*Accessed*/ false); @@ -2325,7 +2378,7 @@ static Value* buildFMulAdd(llvm::BinaryOperator *MulOp, Value *Addend,                             const CodeGenFunction &CGF, CGBuilderTy &Builder,                             bool negMul, bool negAdd) {    assert(!(negMul && negAdd) && "Only one of negMul and negAdd should be set."); -  +    Value *MulOp0 = MulOp->getOperand(0);    Value *MulOp1 = MulOp->getOperand(1);    if (negMul) { @@ -2355,7 +2408,7 @@ static Value* buildFMulAdd(llvm::BinaryOperator *MulOp, Value *Addend,  // Checks that (a) the operation is fusable, and (b) -ffp-contract=on.  // Does NOT check the type of the operation - it's assumed that this function  // will be called from contexts where it's known that the type is contractable. -static Value* tryEmitFMulAdd(const BinOpInfo &op,  +static Value* tryEmitFMulAdd(const BinOpInfo &op,                           const CodeGenFunction &CGF, CGBuilderTy &Builder,                           bool isSub=false) { @@ -2503,7 +2556,7 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) {      divisor = CGF.CGM.getSize(elementSize);    } -   +    // Otherwise, do a full sdiv. This uses the "exact" form of sdiv, since    // pointer difference in C is only defined in the case where both operands    // are pointing to elements of an array. @@ -2809,7 +2862,7 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {      return RHS;    // Otherwise, reload the value. -  return EmitLoadOfLValue(LHS); +  return EmitLoadOfLValue(LHS, E->getExprLoc());  }  Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { @@ -2828,9 +2881,9 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {      Value *And = Builder.CreateAnd(LHS, RHS);      return Builder.CreateSExt(And, ConvertType(E->getType()), "sext");    } -   +    llvm::Type *ResTy = ConvertType(E->getType()); -   +    // If we have 0 && RHS, see if we can elide RHS, if so, just return 0.    // If we have 1 && X, just emit X without inserting the control flow.    bool LHSCondVal; @@ -2899,9 +2952,9 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {      Value *Or = Builder.CreateOr(LHS, RHS);      return Builder.CreateSExt(Or, ConvertType(E->getType()), "sext");    } -   +    llvm::Type *ResTy = ConvertType(E->getType()); -   +    // If we have 1 || RHS, see if we can elide RHS, if so, just return 1.    // If we have 0 || X, just emit X without inserting the control flow.    bool LHSCondVal; @@ -2970,22 +3023,15 @@ Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) {  /// flow into selects in some cases.  static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E,                                                     CodeGenFunction &CGF) { -  E = E->IgnoreParens(); -    // Anything that is an integer or floating point constant is fine. -  if (E->isConstantInitializer(CGF.getContext(), false)) -    return true; - -  // Non-volatile automatic variables too, to get "cond ? X : Y" where -  // X and Y are local variables. -  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) -    if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) -      if (VD->hasLocalStorage() && !(CGF.getContext() -                                     .getCanonicalType(VD->getType()) -                                     .isVolatileQualified())) -        return true; - -  return false; +  return E->IgnoreParens()->isEvaluatable(CGF.getContext()); + +  // Even non-volatile automatic variables can't be evaluated unconditionally. +  // Referencing a thread_local may cause non-trivial initialization work to +  // occur. If we're inside a lambda and one of the variables is from the scope +  // outside the lambda, that function may have returned already. Reading its +  // locals is a bad idea. Also, these reads may introduce races there didn't +  // exist in the source-level program.  } @@ -3023,26 +3069,26 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {    // OpenCL: If the condition is a vector, we can treat this condition like    // the select function. -  if (CGF.getLangOpts().OpenCL  +  if (CGF.getLangOpts().OpenCL        && condExpr->getType()->isVectorType()) {      llvm::Value *CondV = CGF.EmitScalarExpr(condExpr);      llvm::Value *LHS = Visit(lhsExpr);      llvm::Value *RHS = Visit(rhsExpr); -     +      llvm::Type *condType = ConvertType(condExpr->getType());      llvm::VectorType *vecTy = cast<llvm::VectorType>(condType); -     -    unsigned numElem = vecTy->getNumElements();       + +    unsigned numElem = vecTy->getNumElements();      llvm::Type *elemType = vecTy->getElementType(); -     +      llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);      llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec); -    llvm::Value *tmp = Builder.CreateSExt(TestMSB,  +    llvm::Value *tmp = Builder.CreateSExt(TestMSB,                                            llvm::VectorType::get(elemType, -                                                                numElem),          +                                                                numElem),                                            "sext");      llvm::Value *tmp2 = Builder.CreateNot(tmp); -     +      // Cast float to int to perform ANDs if necessary.      llvm::Value *RHSTmp = RHS;      llvm::Value *LHSTmp = LHS; @@ -3053,7 +3099,7 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {        LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());        wasCast = true;      } -     +      llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);      llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);      llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4, "cond"); @@ -3062,7 +3108,7 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {      return tmp5;    } -   +    // If this is a really simple expression (like x ? 4 : 5), emit this as a    // select instead of as control flow.  We can only do this if it is cheap and    // safe to evaluate the LHS and RHS unconditionally. @@ -3116,7 +3162,7 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {  }  Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) { -  return Visit(E->getChosenSubExpr(CGF.getContext())); +  return Visit(E->getChosenSubExpr());  }  Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) { @@ -3138,49 +3184,49 @@ Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *block) {  Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {    Value *Src  = CGF.EmitScalarExpr(E->getSrcExpr());    llvm::Type *DstTy = ConvertType(E->getType()); -   +    // Going from vec4->vec3 or vec3->vec4 is a special case and requires    // a shuffle vector instead of a bitcast.    llvm::Type *SrcTy = Src->getType();    if (isa<llvm::VectorType>(DstTy) && isa<llvm::VectorType>(SrcTy)) {      unsigned numElementsDst = cast<llvm::VectorType>(DstTy)->getNumElements();      unsigned numElementsSrc = cast<llvm::VectorType>(SrcTy)->getNumElements(); -    if ((numElementsDst == 3 && numElementsSrc == 4)  +    if ((numElementsDst == 3 && numElementsSrc == 4)          || (numElementsDst == 4 && numElementsSrc == 3)) { -       -       + +        // In the case of going from int4->float3, a bitcast is needed before        // doing a shuffle. -      llvm::Type *srcElemTy =  +      llvm::Type *srcElemTy =        cast<llvm::VectorType>(SrcTy)->getElementType(); -      llvm::Type *dstElemTy =  +      llvm::Type *dstElemTy =        cast<llvm::VectorType>(DstTy)->getElementType(); -       +        if ((srcElemTy->isIntegerTy() && dstElemTy->isFloatTy())            || (srcElemTy->isFloatTy() && dstElemTy->isIntegerTy())) {          // Create a float type of the same size as the source or destination.          llvm::VectorType *newSrcTy = llvm::VectorType::get(dstElemTy,                                                                   numElementsSrc); -         +          Src = Builder.CreateBitCast(Src, newSrcTy, "astypeCast");        } -       +        llvm::Value *UnV = llvm::UndefValue::get(Src->getType()); -       +        SmallVector<llvm::Constant*, 3> Args;        Args.push_back(Builder.getInt32(0));        Args.push_back(Builder.getInt32(1));        Args.push_back(Builder.getInt32(2)); -  +        if (numElementsDst == 4)          Args.push_back(llvm::UndefValue::get(CGF.Int32Ty)); -       +        llvm::Constant *Mask = llvm::ConstantVector::get(Args); -       +        return Builder.CreateShuffleVector(Src, UnV, Mask, "astype");      }    } -   +    return Builder.CreateBitCast(Src, DstTy, "astype");  } @@ -3248,14 +3294,14 @@ LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {      llvm::Value *Src = EmitScalarExpr(BaseExpr);      Builder.CreateStore(Src, V);      V = ScalarExprEmitter(*this).EmitLoadOfLValue( -      MakeNaturalAlignAddrLValue(V, E->getType())); +      MakeNaturalAlignAddrLValue(V, E->getType()), E->getExprLoc());    } else {      if (E->isArrow())        V = ScalarExprEmitter(*this).EmitLoadOfLValue(BaseExpr);      else        V = EmitLValue(BaseExpr).getAddress();    } -   +    // build Class* type    ClassPtrTy = ClassPtrTy->getPointerTo();    V = Builder.CreateBitCast(V, ClassPtrTy); @@ -3283,7 +3329,7 @@ LValue CodeGenFunction::EmitCompoundAssignmentLValue(    COMPOUND_OP(Xor);    COMPOUND_OP(Or);  #undef COMPOUND_OP -       +    case BO_PtrMemD:    case BO_PtrMemI:    case BO_Mul: @@ -3308,6 +3354,6 @@ LValue CodeGenFunction::EmitCompoundAssignmentLValue(    case BO_Comma:      llvm_unreachable("Not valid compound assignment operators");    } -    +    llvm_unreachable("Unhandled compound assignment operator");  } diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 713509bf67389..0bda053f35f72 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -20,6 +20,7 @@  #include "clang/AST/DeclObjC.h"  #include "clang/AST/StmtObjC.h"  #include "clang/Basic/Diagnostic.h" +#include "clang/CodeGen/CGFunctionInfo.h"  #include "llvm/ADT/STLExtras.h"  #include "llvm/Support/CallSite.h"  #include "llvm/IR/DataLayout.h" @@ -468,8 +469,8 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,                                        SourceLocation StartLoc) {    FunctionArgList args;    // Check if we should generate debug info for this method. -  if (!OMD->hasAttr<NoDebugAttr>()) -    maybeInitializeDebugInfo(); +  if (OMD->hasAttr<NoDebugAttr>()) +    DebugInfo = NULL; // disable debug info indefinitely for this function    llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD); @@ -925,7 +926,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,      QualType ivarType = ivar->getType();      switch (getEvaluationKind(ivarType)) {      case TEK_Complex: { -      ComplexPairTy pair = EmitLoadOfComplex(LV); +      ComplexPairTy pair = EmitLoadOfComplex(LV, SourceLocation());        EmitStoreOfComplex(pair,                           MakeNaturalAlignAddrLValue(ReturnValue, ivarType),                           /*init*/ true); @@ -949,7 +950,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,          // Otherwise we want to do a simple load, suppressing the          // final autorelease.          } else { -          value = EmitLoadOfLValue(LV).getScalarVal(); +          value = EmitLoadOfLValue(LV, SourceLocation()).getScalarVal();            AutoreleaseResult = false;          } @@ -1048,8 +1049,6 @@ static void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF,                                                        FunctionType::ExtInfo(),                                                        RequiredArgs::All),                 copyCppAtomicObjectFn, ReturnValueSlot(), args); -   -  } @@ -1404,7 +1403,7 @@ llvm::Value *CodeGenFunction::LoadObjCSelf() {    VarDecl *Self = cast<ObjCMethodDecl>(CurFuncDecl)->getSelfDecl();    DeclRefExpr DRE(Self, /*is enclosing local*/ (CurFuncDecl != CurCodeDecl),                    Self->getType(), VK_LValue, SourceLocation()); -  return EmitLoadOfScalar(EmitDeclRefLValue(&DRE)); +  return EmitLoadOfScalar(EmitDeclRefLValue(&DRE), SourceLocation());  }  QualType CodeGenFunction::TypeOfSelfObject() { @@ -2084,7 +2083,7 @@ llvm::Value *CodeGenFunction::EmitARCStoreStrong(LValue dst,    newValue = EmitARCRetain(type, newValue);    // Read the old value. -  llvm::Value *oldValue = EmitLoadOfScalar(dst); +  llvm::Value *oldValue = EmitLoadOfScalar(dst, SourceLocation());    // Store.  We do this before the release so that any deallocs won't    // see the old value. @@ -2355,7 +2354,8 @@ static TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,    case Qualifiers::OCL_ExplicitNone:    case Qualifiers::OCL_Strong:    case Qualifiers::OCL_Autoreleasing: -    return TryEmitResult(CGF.EmitLoadOfLValue(lvalue).getScalarVal(), +    return TryEmitResult(CGF.EmitLoadOfLValue(lvalue, +                                              SourceLocation()).getScalarVal(),                           false);    case Qualifiers::OCL_Weak: @@ -2381,7 +2381,8 @@ static TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,      LValue lv = CGF.EmitLValue(e);      // Load the object pointer. -    llvm::Value *result = CGF.EmitLoadOfLValue(lv).getScalarVal(); +    llvm::Value *result = CGF.EmitLoadOfLValue(lv, +                                               SourceLocation()).getScalarVal();      // Set the source pointer to NULL.      CGF.EmitStoreOfScalar(getNullForVariable(lv.getAddress()), lv); @@ -2784,8 +2785,7 @@ CodeGenFunction::EmitARCStoreStrong(const BinaryOperator *e,    // If the RHS was emitted retained, expand this.    if (hasImmediateRetain) { -    llvm::Value *oldValue = -      EmitLoadOfScalar(lvalue); +    llvm::Value *oldValue = EmitLoadOfScalar(lvalue, SourceLocation());      EmitStoreOfScalar(value, lvalue);      EmitARCRelease(oldValue, lvalue.isARCPreciseLifetime());    } else { @@ -2905,9 +2905,6 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction(                             "__assign_helper_atomic_property_",                             &CGM.getModule()); -  // Initialize debug info if needed. -  maybeInitializeDebugInfo(); -      StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());    DeclRefExpr DstExpr(&dstDecl, false, DestTy, @@ -2988,9 +2985,6 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction(    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,                           "__copy_helper_atomic_property_", &CGM.getModule()); -  // Initialize debug info if needed. -  maybeInitializeDebugInfo(); -      StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());    DeclRefExpr SrcExpr(&srcDecl, false, SrcTy, diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index fbf8a1abb0139..a7ab8507014fc 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -454,13 +454,15 @@ protected:    virtual llvm::Value *LookupIMP(CodeGenFunction &CGF,                                   llvm::Value *&Receiver,                                   llvm::Value *cmd, -                                 llvm::MDNode *node) = 0; +                                 llvm::MDNode *node, +                                 MessageSendInfo &MSI) = 0;    /// Looks up the method for sending a message to a superclass.  This    /// mechanism differs between the GCC and GNU runtimes, so this method must    /// be overridden in subclasses.    virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF,                                        llvm::Value *ObjCSuper, -                                      llvm::Value *cmd) = 0; +                                      llvm::Value *cmd, +                                      MessageSendInfo &MSI) = 0;    /// Libobjc2 uses a bitfield representation where small(ish) bitfields are    /// stored in a 64-bit value with the low bit set to 1 and the remaining 63    /// bits set to their values, LSB first, while larger ones are stored in a @@ -596,7 +598,8 @@ protected:    virtual llvm::Value *LookupIMP(CodeGenFunction &CGF,                                   llvm::Value *&Receiver,                                   llvm::Value *cmd, -                                 llvm::MDNode *node) { +                                 llvm::MDNode *node, +                                 MessageSendInfo &MSI) {      CGBuilderTy &Builder = CGF.Builder;      llvm::Value *args[] = {              EnforceType(Builder, Receiver, IdTy), @@ -607,7 +610,8 @@ protected:    }    virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF,                                        llvm::Value *ObjCSuper, -                                      llvm::Value *cmd) { +                                      llvm::Value *cmd, +                                      MessageSendInfo &MSI) {        CGBuilderTy &Builder = CGF.Builder;        llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,            PtrToObjCSuperTy), cmd}; @@ -655,7 +659,8 @@ class CGObjCGNUstep : public CGObjCGNU {      virtual llvm::Value *LookupIMP(CodeGenFunction &CGF,                                     llvm::Value *&Receiver,                                     llvm::Value *cmd, -                                   llvm::MDNode *node) { +                                   llvm::MDNode *node, +                                   MessageSendInfo &MSI) {        CGBuilderTy &Builder = CGF.Builder;        llvm::Function *LookupFn = SlotLookupFn; @@ -693,7 +698,8 @@ class CGObjCGNUstep : public CGObjCGNU {      }      virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF,                                          llvm::Value *ObjCSuper, -                                        llvm::Value *cmd) { +                                        llvm::Value *cmd, +                                        MessageSendInfo &MSI) {        CGBuilderTy &Builder = CGF.Builder;        llvm::Value *lookupArgs[] = {ObjCSuper, cmd}; @@ -790,38 +796,52 @@ class CGObjCGNUstep : public CGObjCGNU {      }  }; -/// Support for the ObjFW runtime. Support here is due to -/// Jonathan Schleifer <js@webkeks.org>, the ObjFW maintainer. +/// Support for the ObjFW runtime.  class CGObjCObjFW: public CGObjCGNU {  protected:    /// The GCC ABI message lookup function.  Returns an IMP pointing to the    /// method implementation for this message.    LazyRuntimeFunction MsgLookupFn; +  /// stret lookup function.  While this does not seem to make sense at the +  /// first look, this is required to call the correct forwarding function. +  LazyRuntimeFunction MsgLookupFnSRet;    /// The GCC ABI superclass message lookup function.  Takes a pointer to a    /// structure describing the receiver and the class, and a selector as    /// arguments.  Returns the IMP for the corresponding method. -  LazyRuntimeFunction MsgLookupSuperFn; +  LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;    virtual llvm::Value *LookupIMP(CodeGenFunction &CGF,                                   llvm::Value *&Receiver,                                   llvm::Value *cmd, -                                 llvm::MDNode *node) { +                                 llvm::MDNode *node, +                                 MessageSendInfo &MSI) {      CGBuilderTy &Builder = CGF.Builder;      llvm::Value *args[] = {              EnforceType(Builder, Receiver, IdTy),              EnforceType(Builder, cmd, SelectorTy) }; -    llvm::CallSite imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args); + +    llvm::CallSite imp; +    if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) +      imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFnSRet, args); +    else +      imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args); +      imp->setMetadata(msgSendMDKind, node);      return imp.getInstruction();    }    virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF,                                        llvm::Value *ObjCSuper, -                                      llvm::Value *cmd) { +                                      llvm::Value *cmd, +                                      MessageSendInfo &MSI) {        CGBuilderTy &Builder = CGF.Builder;        llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,            PtrToObjCSuperTy), cmd}; -      return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs); + +      if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) +        return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFnSRet, lookupArgs); +      else +        return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs);      }    virtual llvm::Value *GetClassNamed(CodeGenFunction &CGF, @@ -847,9 +867,13 @@ public:    CGObjCObjFW(CodeGenModule &Mod): CGObjCGNU(Mod, 9, 3) {      // IMP objc_msg_lookup(id, SEL);      MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy, NULL); +    MsgLookupFnSRet.init(&CGM, "objc_msg_lookup_stret", IMPTy, IdTy, +                         SelectorTy, NULL);      // IMP objc_msg_lookup_super(struct objc_super*, SEL);      MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy,                            PtrToObjCSuperTy, SelectorTy, NULL); +    MsgLookupSuperFnSRet.init(&CGM, "objc_msg_lookup_super_stret", IMPTy, +                              PtrToObjCSuperTy, SelectorTy, NULL);    }  };  } // end anonymous namespace @@ -1041,7 +1065,7 @@ llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {  llvm::Value *CGObjCGNU::GetSelector(CodeGenFunction &CGF, Selector Sel,      const std::string &TypeEncoding, bool lval) { -  SmallVector<TypedSelector, 2> &Types = SelectorTable[Sel]; +  SmallVectorImpl<TypedSelector> &Types = SelectorTable[Sel];    llvm::GlobalAlias *SelValue = 0; @@ -1291,7 +1315,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF,    ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy);    // Get the IMP -  llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd); +  llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);    imp = EnforceType(Builder, imp, MSI.MessengerType);    llvm::Value *impMD[] = { @@ -1390,7 +1414,7 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF,    // given platform), so we     switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {      case CodeGenOptions::Legacy: -      imp = LookupIMP(CGF, Receiver, cmd, node); +      imp = LookupIMP(CGF, Receiver, cmd, node, MSI);        break;      case CodeGenOptions::Mixed:      case CodeGenOptions::NonLegacy: @@ -1414,8 +1438,7 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF,    imp = EnforceType(Builder, imp, MSI.MessengerType);    llvm::Instruction *call; -  RValue msgRet = CGF.EmitCall(MSI.CallInfo, imp, Return, ActualArgs, -      0, &call); +  RValue msgRet = CGF.EmitCall(MSI.CallInfo, imp, Return, ActualArgs, 0, &call);    call->setMetadata(msgSendMDKind, node); diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index e8498b06ad2f2..2b2a5b8376082 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -23,6 +23,7 @@  #include "clang/AST/RecordLayout.h"  #include "clang/AST/StmtObjC.h"  #include "clang/Basic/LangOptions.h" +#include "clang/CodeGen/CGFunctionInfo.h"  #include "clang/Frontend/CodeGenOptions.h"  #include "llvm/ADT/DenseSet.h"  #include "llvm/ADT/SetVector.h" @@ -4348,7 +4349,7 @@ void CGObjCCommonMac::EmitImageInfo() {    // Indicate whether we're compiling this to run on a simulator.    const llvm::Triple &Triple = CGM.getTarget().getTriple(); -  if (Triple.getOS() == llvm::Triple::IOS && +  if (Triple.isiOS() &&        (Triple.getArch() == llvm::Triple::x86 ||         Triple.getArch() == llvm::Triple::x86_64))      Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated", @@ -5757,6 +5758,9 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData(    };    if (!Values[1])      Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy); +  if (!Values[3]) +    Values[3] = llvm::Constant::getNullValue( +                  llvm::PointerType::getUnqual(ObjCTypes.ImpnfABITy));    llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,                                                     Values);    llvm::GlobalVariable *GV = GetClassGlobal(ClassName); @@ -5800,14 +5804,21 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {        llvm::GlobalValue::ExternalLinkage,        0,        "_objc_empty_cache"); - -    ObjCEmptyVtableVar = new llvm::GlobalVariable( -      CGM.getModule(), -      ObjCTypes.ImpnfABITy, -      false, -      llvm::GlobalValue::ExternalLinkage, -      0, -      "_objc_empty_vtable"); +     +    // Make this entry NULL for any iOS device target, any iOS simulator target, +    // OS X with deployment target 10.9 or later. +    const llvm::Triple &Triple = CGM.getTarget().getTriple(); +    if (Triple.isiOS() || (Triple.isMacOSX() && !Triple.isMacOSXVersionLT(10, 9))) +      // This entry will be null. +      ObjCEmptyVtableVar = 0; +    else +      ObjCEmptyVtableVar = new llvm::GlobalVariable( +                                                    CGM.getModule(), +                                                    ObjCTypes.ImpnfABITy, +                                                    false, +                                                    llvm::GlobalValue::ExternalLinkage, +                                                    0, +                                                    "_objc_empty_vtable");    }    assert(ID->getClassInterface() &&           "CGObjCNonFragileABIMac::GenerateClass - class is 0"); diff --git a/lib/CodeGen/CGObjCRuntime.cpp b/lib/CodeGen/CGObjCRuntime.cpp index 9c0d5189f8152..d097b6fad2c2e 100644 --- a/lib/CodeGen/CGObjCRuntime.cpp +++ b/lib/CodeGen/CGObjCRuntime.cpp @@ -20,6 +20,7 @@  #include "CodeGenModule.h"  #include "clang/AST/RecordLayout.h"  #include "clang/AST/StmtObjC.h" +#include "clang/CodeGen/CGFunctionInfo.h"  #include "llvm/Support/CallSite.h"  using namespace clang; diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp index 40dc6bfa3b0e9..aa687b9560985 100644 --- a/lib/CodeGen/CGRTTI.cpp +++ b/lib/CodeGen/CGRTTI.cpp @@ -332,6 +332,7 @@ getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty) {    switch (Ty->getLinkage()) {    case NoLinkage: +  case VisibleNoLinkage:    case InternalLinkage:    case UniqueExternalLinkage:      return llvm::GlobalValue::InternalLinkage; @@ -507,60 +508,6 @@ void RTTIBuilder::BuildVTablePointer(const Type *Ty) {    Fields.push_back(VTable);  } -// maybeUpdateRTTILinkage - Will update the linkage of the RTTI data structures -// from available_externally to the correct linkage if necessary. An example of -// this is: -// -//   struct A { -//     virtual void f(); -//   }; -// -//   const std::type_info &g() { -//     return typeid(A); -//   } -// -//   void A::f() { } -// -// When we're generating the typeid(A) expression, we do not yet know that -// A's key function is defined in this translation unit, so we will give the -// typeinfo and typename structures available_externally linkage. When A::f -// forces the vtable to be generated, we need to change the linkage of the -// typeinfo and typename structs, otherwise we'll end up with undefined -// externals when linking. -static void  -maybeUpdateRTTILinkage(CodeGenModule &CGM, llvm::GlobalVariable *GV, -                       QualType Ty) { -  // We're only interested in globals with available_externally linkage. -  if (!GV->hasAvailableExternallyLinkage()) -    return; - -  // Get the real linkage for the type. -  llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(CGM, Ty); - -  // If variable is supposed to have available_externally linkage, we don't -  // need to do anything. -  if (Linkage == llvm::GlobalVariable::AvailableExternallyLinkage) -    return; - -  // Update the typeinfo linkage. -  GV->setLinkage(Linkage); - -  // Get the typename global. -  SmallString<256> OutName; -  llvm::raw_svector_ostream Out(OutName); -  CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out); -  Out.flush(); -  StringRef Name = OutName.str(); - -  llvm::GlobalVariable *TypeNameGV = CGM.getModule().getNamedGlobal(Name); - -  assert(TypeNameGV->hasAvailableExternallyLinkage() && -         "Type name has different linkage from type info!"); - -  // And update its linkage. -  TypeNameGV->setLinkage(Linkage); -} -  llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {    // We want to operate on the canonical type.    Ty = CGM.getContext().getCanonicalType(Ty); @@ -574,7 +521,8 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {    llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);    if (OldGV && !OldGV->isDeclaration()) { -    maybeUpdateRTTILinkage(CGM, OldGV, Ty); +    assert(!OldGV->hasAvailableExternallyLinkage() && +           "available_externally typeinfos not yet implemented");      return llvm::ConstantExpr::getBitCast(OldGV, CGM.Int8PtrTy);    } @@ -898,7 +846,7 @@ void RTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {      CharUnits Offset;      if (Base->isVirtual())        Offset =  -        CGM.getVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl); +        CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);      else {        const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);        Offset = Layout.getBaseClassOffset(BaseDecl); @@ -1024,6 +972,6 @@ void CodeGenModule::EmitFundamentalRTTIDescriptors() {                                    Context.UnsignedLongLongTy, Context.FloatTy,                                    Context.DoubleTy, Context.LongDoubleTy,                                    Context.Char16Ty, Context.Char32Ty }; -  for (unsigned i = 0; i < sizeof(FundamentalTypes)/sizeof(QualType); ++i) +  for (unsigned i = 0; i < llvm::array_lengthof(FundamentalTypes); ++i)      EmitFundamentalRTTIDescriptor(FundamentalTypes[i]);  } diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index 30ab528ffbe4e..ab92563b21f3b 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -78,9 +78,6 @@ public:    /// Packed - Whether the resulting LLVM struct will be packed or not.    bool Packed; -   -  /// IsMsStruct - Whether ms_struct is in effect or not -  bool IsMsStruct;  private:    CodeGenTypes &Types; @@ -117,7 +114,7 @@ private:                         RecordDecl::field_iterator &FI,                         RecordDecl::field_iterator FE); -  /// LayoutField - try to layout all fields in the record decl. +  /// LayoutFields - try to layout all fields in the record decl.    /// Returns false if the operation failed because the struct is not packed.    bool LayoutFields(const RecordDecl *D); @@ -195,8 +192,7 @@ public:    CGRecordLayoutBuilder(CodeGenTypes &Types)      : BaseSubobjectType(0),        IsZeroInitializable(true), IsZeroInitializableAsBase(true), -      Packed(false), IsMsStruct(false), -      Types(Types) { } +      Packed(false), Types(Types) { }    /// Layout - Will layout a RecordDecl.    void Layout(const RecordDecl *D); @@ -205,10 +201,9 @@ public:  }  void CGRecordLayoutBuilder::Layout(const RecordDecl *D) { -  Alignment = Types.getContext().getASTRecordLayout(D).getAlignment(); -  Packed = D->hasAttr<PackedAttr>(); -   -  IsMsStruct = D->isMsStruct(Types.getContext()); +  const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(D); +  Alignment = Layout.getAlignment(); +  Packed = D->hasAttr<PackedAttr>() || Layout.getSize() % Alignment != 0;    if (D->isUnion()) {      LayoutUnion(D); @@ -702,7 +697,7 @@ CGRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD,    }    // Add a vb-table pointer if the layout insists. -  if (Layout.getVBPtrOffset() != CharUnits::fromQuantity(-1)) { +    if (Layout.hasOwnVBPtr()) {      CharUnits VBPtrOffset = Layout.getVBPtrOffset();      llvm::Type *Vbptr = llvm::Type::getInt32PtrTy(Types.getLLVMContext());      AppendPadding(VBPtrOffset, getTypeAlignment(Vbptr)); @@ -764,20 +759,10 @@ bool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {        return false;    unsigned FieldNo = 0; -  const FieldDecl *LastFD = 0;    for (RecordDecl::field_iterator FI = D->field_begin(), FE = D->field_end();         FI != FE; ++FI, ++FieldNo) {      FieldDecl *FD = *FI; -    if (IsMsStruct) { -      // Zero-length bitfields following non-bitfield members are -      // ignored: -      if (Types.getContext().ZeroBitfieldFollowsNonBitfield(FD, LastFD)) { -        --FieldNo; -        continue; -      } -      LastFD = FD; -    }      // If this field is a bitfield, layout all of the consecutive      // non-zero-length bitfields and the last zero-length bitfield; these will @@ -992,11 +977,11 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D,    // Dump the layout, if requested.    if (getContext().getLangOpts().DumpRecordLayouts) { -    llvm::errs() << "\n*** Dumping IRgen Record Layout\n"; -    llvm::errs() << "Record: "; -    D->dump(); -    llvm::errs() << "\nLayout: "; -    RL->dump(); +    llvm::outs() << "\n*** Dumping IRgen Record Layout\n"; +    llvm::outs() << "Record: "; +    D->dump(llvm::outs()); +    llvm::outs() << "\nLayout: "; +    RL->print(llvm::outs());    }  #ifndef NDEBUG @@ -1028,8 +1013,6 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D,    const ASTRecordLayout &AST_RL = getContext().getASTRecordLayout(D);    RecordDecl::field_iterator it = D->field_begin(); -  const FieldDecl *LastFD = 0; -  bool IsMsStruct = D->isMsStruct(getContext());    for (unsigned i = 0, e = AST_RL.getFieldCount(); i != e; ++i, ++it) {      const FieldDecl *FD = *it; @@ -1039,25 +1022,12 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D,        unsigned FieldNo = RL->getLLVMFieldNo(FD);        assert(AST_RL.getFieldOffset(i) == SL->getElementOffsetInBits(FieldNo) &&               "Invalid field offset!"); -      LastFD = FD;        continue;      } - -    if (IsMsStruct) { -      // Zero-length bitfields following non-bitfield members are -      // ignored: -      if (getContext().ZeroBitfieldFollowsNonBitfield(FD, LastFD)) { -        --i; -        continue; -      } -      LastFD = FD; -    }      // Ignore unnamed bit-fields. -    if (!FD->getDeclName()) { -      LastFD = FD; +    if (!FD->getDeclName())        continue; -    }      // Don't inspect zero-length bitfields.      if (FD->getBitWidthValue(getContext()) == 0) diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index 5e2ebe0d9cd46..0bc51ddb51783 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -16,12 +16,14 @@  #include "CodeGenModule.h"  #include "TargetInfo.h"  #include "clang/AST/StmtVisitor.h" +#include "clang/Sema/SemaDiagnostic.h"  #include "clang/Basic/PrettyStackTrace.h"  #include "clang/Basic/TargetInfo.h"  #include "llvm/ADT/StringExtras.h"  #include "llvm/IR/DataLayout.h"  #include "llvm/IR/InlineAsm.h"  #include "llvm/IR/Intrinsics.h" +#include "llvm/Support/CallSite.h"  using namespace clang;  using namespace CodeGen; @@ -32,14 +34,10 @@ using namespace CodeGen;  void CodeGenFunction::EmitStopPoint(const Stmt *S) {    if (CGDebugInfo *DI = getDebugInfo()) {      SourceLocation Loc; -    if (isa<DeclStmt>(S)) -      Loc = S->getLocEnd(); -    else -      Loc = S->getLocStart(); +    Loc = S->getLocStart();      DI->EmitLocation(Builder, Loc); -    //if (++NumStopPoints == 1) -      LastStopPoint = Loc; +    LastStopPoint = Loc;    }  } @@ -77,6 +75,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {    case Stmt::SEHExceptStmtClass:    case Stmt::SEHFinallyStmtClass:    case Stmt::MSDependentExistsStmtClass: +  case Stmt::OMPParallelDirectiveClass:      llvm_unreachable("invalid statement class to emit generically");    case Stmt::NullStmtClass:    case Stmt::CompoundStmtClass: @@ -137,8 +136,10 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {    case Stmt::SwitchStmtClass:   EmitSwitchStmt(cast<SwitchStmt>(*S));     break;    case Stmt::GCCAsmStmtClass:   // Intentional fall-through.    case Stmt::MSAsmStmtClass:    EmitAsmStmt(cast<AsmStmt>(*S));           break; -  case Stmt::CapturedStmtClass: -    EmitCapturedStmt(cast<CapturedStmt>(*S)); +  case Stmt::CapturedStmtClass: { +    const CapturedStmt *CS = cast<CapturedStmt>(S); +    EmitCapturedStmt(*CS, CS->getCapturedRegionKind()); +    }      break;    case Stmt::ObjCAtTryStmtClass:      EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S)); @@ -167,8 +168,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {      break;    case Stmt::CXXForRangeStmtClass:      EmitCXXForRangeStmt(cast<CXXForRangeStmt>(*S)); +    break;    case Stmt::SEHTryStmtClass: -    // FIXME Not yet implemented +    EmitSEHTryStmt(cast<SEHTryStmt>(*S));      break;    }  } @@ -195,8 +197,8 @@ bool CodeGenFunction::EmitSimpleStmt(const Stmt *S) {  /// EmitCompoundStmt - Emit a compound statement {..} node.  If GetLast is true,  /// this captures the expression result of the last sub-statement and returns it  /// (for use by the statement expression extension). -RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, -                                         AggValueSlot AggSlot) { +llvm::Value* CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, +                                               AggValueSlot AggSlot) {    PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),S.getLBracLoc(),                               "LLVM IR generation of compound statement ('{}')"); @@ -206,17 +208,17 @@ RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,    return EmitCompoundStmtWithoutScope(S, GetLast, AggSlot);  } -RValue CodeGenFunction::EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool GetLast, -                                         AggValueSlot AggSlot) { +llvm::Value* +CodeGenFunction::EmitCompoundStmtWithoutScope(const CompoundStmt &S, +                                              bool GetLast, +                                              AggValueSlot AggSlot) {    for (CompoundStmt::const_body_iterator I = S.body_begin(),         E = S.body_end()-GetLast; I != E; ++I)      EmitStmt(*I); -  RValue RV; -  if (!GetLast) -    RV = RValue::get(0); -  else { +  llvm::Value *RetAlloca = 0; +  if (GetLast) {      // We have to special case labels here.  They are statements, but when put      // at the end of a statement expression, they yield the value of their      // subexpression.  Handle this by walking through all labels we encounter, @@ -229,10 +231,21 @@ RValue CodeGenFunction::EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool      EnsureInsertPoint(); -    RV = EmitAnyExpr(cast<Expr>(LastStmt), AggSlot); +    QualType ExprTy = cast<Expr>(LastStmt)->getType(); +    if (hasAggregateEvaluationKind(ExprTy)) { +      EmitAggExpr(cast<Expr>(LastStmt), AggSlot); +    } else { +      // We can't return an RValue here because there might be cleanups at +      // the end of the StmtExpr.  Because of that, we have to emit the result +      // here into a temporary alloca. +      RetAlloca = CreateMemTemp(ExprTy); +      EmitAnyExprToMem(cast<Expr>(LastStmt), RetAlloca, Qualifiers(), +                       /*IsInit*/false); +    } +          } -  return RV; +  return RetAlloca;  }  void CodeGenFunction::SimplifyForwardingBlocks(llvm::BasicBlock *BB) { @@ -416,7 +429,7 @@ void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) {  void CodeGenFunction::EmitIfStmt(const IfStmt &S) {    // C99 6.8.4.1: The first substatement is executed if the expression compares    // unequal to 0.  The condition must be a scalar type. -  RunCleanupsScope ConditionScope(*this); +  LexicalScope ConditionScope(*this, S.getSourceRange());    if (S.getConditionVariable())      EmitAutoVarDecl(*S.getConditionVariable()); @@ -626,15 +639,14 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) {    // Create a cleanup scope for the condition variable cleanups.    RunCleanupsScope ConditionScope(*this); -  llvm::Value *BoolCondVal = 0;    if (S.getCond()) {      // If the for statement has a condition scope, emit the local variable      // declaration. -    llvm::BasicBlock *ExitBlock = LoopExit.getBlock();      if (S.getConditionVariable()) {        EmitAutoVarDecl(*S.getConditionVariable());      } +    llvm::BasicBlock *ExitBlock = LoopExit.getBlock();      // If there are any cleanups between here and the loop-exit scope,      // create a block to stage a loop exit along.      if (ForScope.requiresCleanups()) @@ -645,8 +657,7 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) {      // C99 6.8.5p2/p4: The first substatement is executed if the expression      // compares unequal to 0.  The condition must be a scalar type. -    BoolCondVal = EvaluateExprAsBool(S.getCond()); -    Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock); +    EmitBranchOnBoolExpr(S.getCond(), ForBody, ExitBlock);      if (ExitBlock != LoopExit.getBlock()) {        EmitBlock(ExitBlock); @@ -726,8 +737,7 @@ void CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S) {    // The body is executed if the expression, contextually converted    // to bool, is true. -  llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); -  Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock); +  EmitBranchOnBoolExpr(S.getCond(), ForBody, ExitBlock);    if (ExitBlock != LoopExit.getBlock()) {      EmitBlock(ExitBlock); @@ -818,7 +828,7 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {    } else if (FnRetTy->isReferenceType()) {      // If this function returns a reference, take the address of the expression      // rather than the value. -    RValue Result = EmitReferenceBindingToExpr(RV, /*InitializedDecl=*/0); +    RValue Result = EmitReferenceBindingToExpr(RV);      Builder.CreateStore(Result.getScalarVal(), ReturnValue);    } else {      switch (getEvaluationKind(RV->getType())) { @@ -842,9 +852,9 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {      }    } -  NumReturnExprs += 1; +  ++NumReturnExprs;    if (RV == 0 || RV->isEvaluatable(getContext())) -    NumSimpleReturnExprs += 1; +    ++NumSimpleReturnExprs;    cleanupScope.ForceCleanup();    EmitBranchThroughCleanup(ReturnBlock); @@ -1334,7 +1344,7 @@ SimplifyConstraint(const char *Constraint, const TargetInfo &Target,        break;      case '#': // Ignore the rest of the constraint alternative.        while (Constraint[1] && Constraint[1] != ',') -	Constraint++; +        Constraint++;        break;      case ',':        Result += "|"; @@ -1398,11 +1408,12 @@ AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr,  llvm::Value*  CodeGenFunction::EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info,                                      LValue InputValue, QualType InputType, -                                    std::string &ConstraintStr) { +                                    std::string &ConstraintStr, +                                    SourceLocation Loc) {    llvm::Value *Arg;    if (Info.allowsRegister() || !Info.allowsMemory()) {      if (CodeGenFunction::hasScalarEvaluationKind(InputType)) { -      Arg = EmitLoadOfLValue(InputValue).getScalarVal(); +      Arg = EmitLoadOfLValue(InputValue, Loc).getScalarVal();      } else {        llvm::Type *Ty = ConvertType(InputType);        uint64_t Size = CGM.getDataLayout().getTypeSizeInBits(Ty); @@ -1435,7 +1446,8 @@ llvm::Value* CodeGenFunction::EmitAsmInput(    InputExpr = InputExpr->IgnoreParenNoopCasts(getContext());    LValue Dest = EmitLValue(InputExpr); -  return EmitAsmInputLValue(Info, Dest, InputExpr->getType(), ConstraintStr); +  return EmitAsmInputLValue(Info, Dest, InputExpr->getType(), ConstraintStr, +                            InputExpr->getExprLoc());  }  /// getAsmSrcLocInfo - Return the !srcloc metadata node to attach to an inline @@ -1559,10 +1571,15 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {            ResultRegTypes.back() = ConvertType(InputTy);          }        } -      if (llvm::Type* AdjTy =  +      if (llvm::Type* AdjTy =              getTargetHooks().adjustInlineAsmType(*this, OutputConstraint,                                                   ResultRegTypes.back()))          ResultRegTypes.back() = AdjTy; +      else { +        CGM.getDiags().Report(S.getAsmLoc(), +                              diag::err_asm_invalid_type_in_input) +            << OutExpr->getType() << OutputConstraint; +      }      } else {        ArgTypes.push_back(Dest.getAddress()->getType());        Args.push_back(Dest.getAddress()); @@ -1575,11 +1592,12 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {        const Expr *InputExpr = S.getOutputExpr(i);        llvm::Value *Arg = EmitAsmInputLValue(Info, Dest, InputExpr->getType(), -                                            InOutConstraints); +                                            InOutConstraints, +                                            InputExpr->getExprLoc());        if (llvm::Type* AdjTy = -            getTargetHooks().adjustInlineAsmType(*this, OutputConstraint, -                                                 Arg->getType())) +          getTargetHooks().adjustInlineAsmType(*this, OutputConstraint, +                                               Arg->getType()))          Arg = Builder.CreateBitCast(Arg, AdjTy);        if (Info.allowsRegister()) @@ -1644,6 +1662,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {                getTargetHooks().adjustInlineAsmType(*this, InputConstraint,                                                     Arg->getType()))        Arg = Builder.CreateBitCast(Arg, AdjTy); +    else +      CGM.getDiags().Report(S.getAsmLoc(), diag::err_asm_invalid_type_in_input) +          << InputExpr->getType() << InputConstraint;      ArgTypes.push_back(Arg->getType());      Args.push_back(Arg); @@ -1751,6 +1772,91 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {    }  } -void CodeGenFunction::EmitCapturedStmt(const CapturedStmt &S) { -  llvm_unreachable("not implemented yet"); +static LValue InitCapturedStruct(CodeGenFunction &CGF, const CapturedStmt &S) { +  const RecordDecl *RD = S.getCapturedRecordDecl(); +  QualType RecordTy = CGF.getContext().getRecordType(RD); + +  // Initialize the captured struct. +  LValue SlotLV = CGF.MakeNaturalAlignAddrLValue( +                    CGF.CreateMemTemp(RecordTy, "agg.captured"), RecordTy); + +  RecordDecl::field_iterator CurField = RD->field_begin(); +  for (CapturedStmt::capture_init_iterator I = S.capture_init_begin(), +                                           E = S.capture_init_end(); +       I != E; ++I, ++CurField) { +    LValue LV = CGF.EmitLValueForFieldInitialization(SlotLV, *CurField); +    CGF.EmitInitializerForField(*CurField, LV, *I, ArrayRef<VarDecl *>()); +  } + +  return SlotLV; +} + +/// Generate an outlined function for the body of a CapturedStmt, store any +/// captured variables into the captured struct, and call the outlined function. +llvm::Function * +CodeGenFunction::EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K) { +  const CapturedDecl *CD = S.getCapturedDecl(); +  const RecordDecl *RD = S.getCapturedRecordDecl(); +  assert(CD->hasBody() && "missing CapturedDecl body"); + +  LValue CapStruct = InitCapturedStruct(*this, S); + +  // Emit the CapturedDecl +  CodeGenFunction CGF(CGM, true); +  CGF.CapturedStmtInfo = new CGCapturedStmtInfo(S, K); +  llvm::Function *F = CGF.GenerateCapturedStmtFunction(CD, RD, S.getLocStart()); +  delete CGF.CapturedStmtInfo; + +  // Emit call to the helper function. +  EmitCallOrInvoke(F, CapStruct.getAddress()); + +  return F; +} + +/// Creates the outlined function for a CapturedStmt. +llvm::Function * +CodeGenFunction::GenerateCapturedStmtFunction(const CapturedDecl *CD, +                                              const RecordDecl *RD, +                                              SourceLocation Loc) { +  assert(CapturedStmtInfo && +    "CapturedStmtInfo should be set when generating the captured function"); + +  // Build the argument list. +  ASTContext &Ctx = CGM.getContext(); +  FunctionArgList Args; +  Args.append(CD->param_begin(), CD->param_end()); + +  // Create the function declaration. +  FunctionType::ExtInfo ExtInfo; +  const CGFunctionInfo &FuncInfo = +    CGM.getTypes().arrangeFunctionDeclaration(Ctx.VoidTy, Args, ExtInfo, +                                              /*IsVariadic=*/false); +  llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo); + +  llvm::Function *F = +    llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage, +                           CapturedStmtInfo->getHelperName(), &CGM.getModule()); +  CGM.SetInternalFunctionAttributes(CD, F, FuncInfo); + +  // Generate the function. +  StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args, CD->getBody()->getLocStart()); + +  // Set the context parameter in CapturedStmtInfo. +  llvm::Value *DeclPtr = LocalDeclMap[CD->getContextParam()]; +  assert(DeclPtr && "missing context parameter for CapturedStmt"); +  CapturedStmtInfo->setContextValue(Builder.CreateLoad(DeclPtr)); + +  // If 'this' is captured, load it into CXXThisValue. +  if (CapturedStmtInfo->isCXXThisExprCaptured()) { +    FieldDecl *FD = CapturedStmtInfo->getThisFieldDecl(); +    LValue LV = MakeNaturalAlignAddrLValue(CapturedStmtInfo->getContextValue(), +                                           Ctx.getTagDeclType(RD)); +    LValue ThisLValue = EmitLValueForField(LV, FD); +    CXXThisValue = EmitLoadOfLValue(ThisLValue, Loc).getScalarVal(); +  } + +  CapturedStmtInfo->EmitBody(*this, CD->getBody()); +  FinishFunction(CD->getBodyRBrace()); + +  return F;  } diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp index 98be872a5525e..bfff47058897c 100644 --- a/lib/CodeGen/CGVTT.cpp +++ b/lib/CodeGen/CGVTT.cpp @@ -19,7 +19,8 @@ using namespace clang;  using namespace CodeGen;  static llvm::Constant * -GetAddrOfVTTVTable(CodeGenVTables &CGVT, const CXXRecordDecl *MostDerivedClass, +GetAddrOfVTTVTable(CodeGenVTables &CGVT, CodeGenModule &CGM, +                   const CXXRecordDecl *MostDerivedClass,                     const VTTVTable &VTable,                     llvm::GlobalVariable::LinkageTypes Linkage,                     llvm::DenseMap<BaseSubobject, uint64_t> &AddressPoints) { @@ -27,7 +28,7 @@ GetAddrOfVTTVTable(CodeGenVTables &CGVT, const CXXRecordDecl *MostDerivedClass,      assert(VTable.getBaseOffset().isZero() &&             "Most derived class vtable must have a zero offset!");      // This is a regular vtable. -    return CGVT.GetAddrOfVTable(MostDerivedClass); +    return CGM.getCXXABI().getAddrOfVTable(MostDerivedClass, CharUnits());    }    return CGVT.GenerateConstructionVTable(MostDerivedClass,  @@ -52,7 +53,7 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,    for (const VTTVTable *i = Builder.getVTTVTables().begin(),                         *e = Builder.getVTTVTables().end(); i != e; ++i) {      VTableAddressPoints.push_back(VTableAddressPointsMapTy()); -    VTables.push_back(GetAddrOfVTTVTable(*this, RD, *i, Linkage, +    VTables.push_back(GetAddrOfVTTVTable(*this, CGM, RD, *i, Linkage,                                           VTableAddressPoints.back()));    } @@ -64,8 +65,8 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,      uint64_t AddressPoint;      if (VTTVT.getBase() == RD) {        // Just get the address point for the regular vtable. -      AddressPoint = VTContext.getVTableLayout(RD) -                              .getAddressPoint(i->VTableBase); +      AddressPoint = +          ItaniumVTContext.getVTableLayout(RD).getAddressPoint(i->VTableBase);        assert(AddressPoint != 0 && "Did not find vtable address point!");      } else {        AddressPoint = VTableAddressPoints[i->VTableIndex].lookup(i->VTableBase); @@ -101,12 +102,13 @@ llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) {    SmallString<256> OutName;    llvm::raw_svector_ostream Out(OutName); -  CGM.getCXXABI().getMangleContext().mangleCXXVTT(RD, Out); +  cast<ItaniumMangleContext>(CGM.getCXXABI().getMangleContext()) +      .mangleCXXVTT(RD, Out);    Out.flush();    StringRef Name = OutName.str();    // This will also defer the definition of the VTT. -  (void) GetAddrOfVTable(RD); +  (void) CGM.getCXXABI().getAddrOfVTable(RD, CharUnits());    VTTBuilder Builder(CGM.getContext(), RD, /*GenerateDefinition=*/false); @@ -120,24 +122,6 @@ llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) {    return GV;  } -bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) { -  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); -   -  // We don't have any virtual bases, just return early. -  if (!MD->getParent()->getNumVBases()) -    return false; -   -  // Check if we have a base constructor. -  if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base) -    return true; - -  // Check if we have a base destructor. -  if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) -    return true; -   -  return false; -} -  uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD,                                           BaseSubobject Base) {    BaseSubobjectPairTy ClassSubobjectPair(RD, Base); diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index 069cd5f9e7381..f28d9b67a8f3c 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -16,6 +16,7 @@  #include "CodeGenModule.h"  #include "clang/AST/CXXInheritance.h"  #include "clang/AST/RecordLayout.h" +#include "clang/CodeGen/CGFunctionInfo.h"  #include "clang/Frontend/CodeGenOptions.h"  #include "llvm/ADT/DenseSet.h"  #include "llvm/ADT/SetVector.h" @@ -29,7 +30,14 @@ using namespace clang;  using namespace CodeGen;  CodeGenVTables::CodeGenVTables(CodeGenModule &CGM) -  : CGM(CGM), VTContext(CGM.getContext()) { } +  : CGM(CGM), ItaniumVTContext(CGM.getContext()) { +  if (CGM.getTarget().getCXXABI().isMicrosoft()) { +    // FIXME: Eventually, we should only have one of V*TContexts available. +    // Today we use both in the Microsoft ABI as MicrosoftVFTableContext +    // is not completely supported in CodeGen yet. +    MicrosoftVTContext.reset(new MicrosoftVTableContext(CGM.getContext())); +  } +}  llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD,                                                 const ThunkInfo &Thunk) { @@ -49,53 +57,6 @@ llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD,    return GetOrCreateLLVMFunction(Name, Ty, GD, /*ForVTable=*/true);  } -static llvm::Value *PerformTypeAdjustment(CodeGenFunction &CGF, -                                          llvm::Value *Ptr, -                                          int64_t NonVirtualAdjustment, -                                          int64_t VirtualAdjustment, -                                          bool IsReturnAdjustment) { -  if (!NonVirtualAdjustment && !VirtualAdjustment) -    return Ptr; - -  llvm::Type *Int8PtrTy = CGF.Int8PtrTy; -  llvm::Value *V = CGF.Builder.CreateBitCast(Ptr, Int8PtrTy); - -  if (NonVirtualAdjustment && !IsReturnAdjustment) { -    // Perform the non-virtual adjustment for a base-to-derived cast. -    V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment); -  } - -  if (VirtualAdjustment) { -    llvm::Type *PtrDiffTy =  -      CGF.ConvertType(CGF.getContext().getPointerDiffType()); - -    // Perform the virtual adjustment. -    llvm::Value *VTablePtrPtr =  -      CGF.Builder.CreateBitCast(V, Int8PtrTy->getPointerTo()); -     -    llvm::Value *VTablePtr = CGF.Builder.CreateLoad(VTablePtrPtr); -   -    llvm::Value *OffsetPtr = -      CGF.Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment); -     -    OffsetPtr = CGF.Builder.CreateBitCast(OffsetPtr, PtrDiffTy->getPointerTo()); -     -    // Load the adjustment offset from the vtable. -    llvm::Value *Offset = CGF.Builder.CreateLoad(OffsetPtr); -     -    // Adjust our pointer. -    V = CGF.Builder.CreateInBoundsGEP(V, Offset); -  } - -  if (NonVirtualAdjustment && IsReturnAdjustment) { -    // Perform the non-virtual adjustment for a derived-to-base cast. -    V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment); -  } - -  // Cast back to the original type. -  return CGF.Builder.CreateBitCast(V, Ptr->getType()); -} -  static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD,                                 const ThunkInfo &Thunk, llvm::Function *Fn) {    CGM.setGlobalVisibility(Fn, MD); @@ -174,12 +135,10 @@ static RValue PerformReturnAdjustment(CodeGenFunction &CGF,      CGF.Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull);      CGF.EmitBlock(AdjustNotNull);    } -   -  ReturnValue = PerformTypeAdjustment(CGF, ReturnValue,  -                                      Thunk.Return.NonVirtual,  -                                      Thunk.Return.VBaseOffsetOffset, -                                      /*IsReturnAdjustment*/true); -   + +  ReturnValue = CGF.CGM.getCXXABI().performReturnAdjustment(CGF, ReturnValue, +                                                            Thunk.Return); +    if (NullCheckValue) {      CGF.Builder.CreateBr(AdjustEnd);      CGF.EmitBlock(AdjustNull); @@ -259,11 +218,8 @@ void CodeGenFunction::GenerateVarArgsThunk(    assert(ThisStore && "Store of this should be in entry block?");    // Adjust "this", if necessary.    Builder.SetInsertPoint(ThisStore); -  llvm::Value *AdjustedThisPtr =  -    PerformTypeAdjustment(*this, ThisPtr,  -                          Thunk.This.NonVirtual,  -                          Thunk.This.VCallOffsetOffset, -                          /*IsReturnAdjustment*/false); +  llvm::Value *AdjustedThisPtr = +      CGM.getCXXABI().performThisAdjustment(*this, ThisPtr, Thunk.This);    ThisStore->setOperand(0, AdjustedThisPtr);    if (!Thunk.Return.isEmpty()) { @@ -282,94 +238,99 @@ void CodeGenFunction::GenerateVarArgsThunk(    }  } -void CodeGenFunction::GenerateThunk(llvm::Function *Fn, -                                    const CGFunctionInfo &FnInfo, -                                    GlobalDecl GD, const ThunkInfo &Thunk) { +void CodeGenFunction::StartThunk(llvm::Function *Fn, GlobalDecl GD, +                                 const CGFunctionInfo &FnInfo) { +  assert(!CurGD.getDecl() && "CurGD was already set!"); +  CurGD = GD; + +  // Build FunctionArgs.    const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); -  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); -  QualType ResultType = FPT->getResultType();    QualType ThisType = MD->getThisType(getContext()); - +  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>(); +  QualType ResultType = +    CGM.getCXXABI().HasThisReturn(GD) ? ThisType : FPT->getResultType();    FunctionArgList FunctionArgs; -  // FIXME: It would be nice if more of this code could be shared with  -  // CodeGenFunction::GenerateCode. -    // Create the implicit 'this' parameter declaration. -  CurGD = GD;    CGM.getCXXABI().BuildInstanceFunctionParams(*this, ResultType, FunctionArgs);    // Add the rest of the parameters.    for (FunctionDecl::param_const_iterator I = MD->param_begin(), -       E = MD->param_end(); I != E; ++I) { -    ParmVarDecl *Param = *I; -     -    FunctionArgs.push_back(Param); -  } - -  // Initialize debug info if needed. -  maybeInitializeDebugInfo(); +                                          E = MD->param_end(); +       I != E; ++I) +    FunctionArgs.push_back(*I); +  // Start defining the function.    StartFunction(GlobalDecl(), ResultType, Fn, FnInfo, FunctionArgs,                  SourceLocation()); +  // Since we didn't pass a GlobalDecl to StartFunction, do this ourselves.    CGM.getCXXABI().EmitInstanceFunctionProlog(*this);    CXXThisValue = CXXABIThisValue; +} -  // Adjust the 'this' pointer if necessary. -  llvm::Value *AdjustedThisPtr =  -    PerformTypeAdjustment(*this, LoadCXXThis(),  -                          Thunk.This.NonVirtual,  -                          Thunk.This.VCallOffsetOffset, -                          /*IsReturnAdjustment*/false); -   +void CodeGenFunction::EmitCallAndReturnForThunk(GlobalDecl GD, +                                                llvm::Value *Callee, +                                                const ThunkInfo *Thunk) { +  assert(isa<CXXMethodDecl>(CurGD.getDecl()) && +         "Please use a new CGF for this thunk"); +  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); + +  // Adjust the 'this' pointer if necessary +  llvm::Value *AdjustedThisPtr = Thunk ? CGM.getCXXABI().performThisAdjustment( +                                             *this, LoadCXXThis(), Thunk->This) +                                       : LoadCXXThis(); + +  // Start building CallArgs.    CallArgList CallArgs; -   -  // Add our adjusted 'this' pointer. +  QualType ThisType = MD->getThisType(getContext());    CallArgs.add(RValue::get(AdjustedThisPtr), ThisType); -  // Add the rest of the parameters. +  if (isa<CXXDestructorDecl>(MD)) +    CGM.getCXXABI().adjustCallArgsForDestructorThunk(*this, GD, CallArgs); + +  // Add the rest of the arguments.    for (FunctionDecl::param_const_iterator I = MD->param_begin(), -       E = MD->param_end(); I != E; ++I) { -    ParmVarDecl *param = *I; -    EmitDelegateCallArg(CallArgs, param); -  } +       E = MD->param_end(); I != E; ++I) +    EmitDelegateCallArg(CallArgs, *I, (*I)->getLocStart()); -  // Get our callee. -  llvm::Type *Ty = -    CGM.getTypes().GetFunctionType(CGM.getTypes().arrangeGlobalDeclaration(GD)); -  llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true); +  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();  #ifndef NDEBUG    const CGFunctionInfo &CallFnInfo =      CGM.getTypes().arrangeCXXMethodCall(CallArgs, FPT,                                         RequiredArgs::forPrototypePlus(FPT, 1)); -  assert(CallFnInfo.getRegParm() == FnInfo.getRegParm() && -         CallFnInfo.isNoReturn() == FnInfo.isNoReturn() && -         CallFnInfo.getCallingConvention() == FnInfo.getCallingConvention()); +  assert(CallFnInfo.getRegParm() == CurFnInfo->getRegParm() && +         CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() && +         CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention());    assert(isa<CXXDestructorDecl>(MD) || // ignore dtor return types           similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(), -                 FnInfo.getReturnInfo(), FnInfo.getReturnType())); -  assert(CallFnInfo.arg_size() == FnInfo.arg_size()); -  for (unsigned i = 0, e = FnInfo.arg_size(); i != e; ++i) +                 CurFnInfo->getReturnInfo(), CurFnInfo->getReturnType())); +  assert(CallFnInfo.arg_size() == CurFnInfo->arg_size()); +  for (unsigned i = 0, e = CurFnInfo->arg_size(); i != e; ++i)      assert(similar(CallFnInfo.arg_begin()[i].info,                     CallFnInfo.arg_begin()[i].type, -                   FnInfo.arg_begin()[i].info, FnInfo.arg_begin()[i].type)); +                   CurFnInfo->arg_begin()[i].info, +                   CurFnInfo->arg_begin()[i].type));  #endif -   +    // Determine whether we have a return value slot to use. +  QualType ResultType = +    CGM.getCXXABI().HasThisReturn(GD) ? ThisType : FPT->getResultType();    ReturnValueSlot Slot;    if (!ResultType->isVoidType() && -      FnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect && +      CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&        !hasScalarEvaluationKind(CurFnInfo->getReturnType()))      Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified());    // Now emit our call. -  RValue RV = EmitCall(FnInfo, Callee, Slot, CallArgs, MD); +  RValue RV = EmitCall(*CurFnInfo, Callee, Slot, CallArgs, MD); -  if (!Thunk.Return.isEmpty()) -    RV = PerformReturnAdjustment(*this, ResultType, RV, Thunk); +  // Consider return adjustment if we have ThunkInfo. +  if (Thunk && !Thunk->Return.isEmpty()) +    RV = PerformReturnAdjustment(*this, ResultType, RV, *Thunk); +  // Emit return.    if (!ResultType->isVoidType() && Slot.isNull())      CGM.getCXXABI().EmitReturnFromThunk(*this, RV, ResultType); @@ -377,17 +338,31 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn,    AutoreleaseResult = false;    FinishFunction(); +} + +void CodeGenFunction::GenerateThunk(llvm::Function *Fn, +                                    const CGFunctionInfo &FnInfo, +                                    GlobalDecl GD, const ThunkInfo &Thunk) { +  StartThunk(Fn, GD, FnInfo); + +  // Get our callee. +  llvm::Type *Ty = +    CGM.getTypes().GetFunctionType(CGM.getTypes().arrangeGlobalDeclaration(GD)); +  llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true); + +  // Make the call and return the result. +  EmitCallAndReturnForThunk(GD, Callee, &Thunk);    // Set the right linkage. -  CGM.setFunctionLinkage(MD, Fn); +  CGM.setFunctionLinkage(GD, Fn);    // Set the right visibility. +  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());    setThunkVisibility(CGM, MD, Thunk, Fn);  } -void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk,  -                               bool UseAvailableExternallyLinkage) -{ +void CodeGenVTables::emitThunk(GlobalDecl GD, const ThunkInfo &Thunk, +                               bool ForVTable) {    const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeGlobalDeclaration(GD);    // FIXME: re-use FnInfo in this computation. @@ -425,19 +400,17 @@ void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk,    }    llvm::Function *ThunkFn = cast<llvm::Function>(Entry); +  bool ABIHasKeyFunctions = CGM.getTarget().getCXXABI().hasKeyFunctions(); +  bool UseAvailableExternallyLinkage = ForVTable && ABIHasKeyFunctions;    if (!ThunkFn->isDeclaration()) { -    if (UseAvailableExternallyLinkage) { +    if (!ABIHasKeyFunctions || UseAvailableExternallyLinkage) {        // There is already a thunk emitted for this function, do nothing.        return;      } -    // If a function has a body, it should have available_externally linkage. -    assert(ThunkFn->hasAvailableExternallyLinkage() && -           "Function should have available_externally linkage!"); -      // Change the linkage. -    CGM.setFunctionLinkage(cast<CXXMethodDecl>(GD.getDecl()), ThunkFn); +    CGM.setFunctionLinkage(GD, ThunkFn);      return;    } @@ -449,30 +422,34 @@ void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk,      // expensive/sucky at the moment, so don't generate the thunk unless      // we have to.      // FIXME: Do something better here; GenerateVarArgsThunk is extremely ugly. -    if (!UseAvailableExternallyLinkage) +    if (!UseAvailableExternallyLinkage) {        CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, Thunk); +      CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable); +    }    } else {      // Normal thunk body generation.      CodeGenFunction(CGM).GenerateThunk(ThunkFn, FnInfo, GD, Thunk); +    CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable);    } - -  if (UseAvailableExternallyLinkage) -    ThunkFn->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);  } -void CodeGenVTables::MaybeEmitThunkAvailableExternally(GlobalDecl GD, -                                                       const ThunkInfo &Thunk) { -  // We only want to do this when building with optimizations. -  if (!CGM.getCodeGenOpts().OptimizationLevel) +void CodeGenVTables::maybeEmitThunkForVTable(GlobalDecl GD, +                                             const ThunkInfo &Thunk) { +  // If the ABI has key functions, only the TU with the key function should emit +  // the thunk. However, we can allow inlining of thunks if we emit them with +  // available_externally linkage together with vtables when optimizations are +  // enabled. +  if (CGM.getTarget().getCXXABI().hasKeyFunctions() && +      !CGM.getCodeGenOpts().OptimizationLevel)      return;    // We can't emit thunks for member functions with incomplete types.    const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());    if (!CGM.getTypes().isFuncTypeConvertible( -                                cast<FunctionType>(MD->getType().getTypePtr()))) +           MD->getType()->castAs<FunctionType>()))      return; -  EmitThunk(GD, Thunk, /*UseAvailableExternallyLinkage=*/true); +  emitThunk(GD, Thunk, /*ForVTable=*/true);  }  void CodeGenVTables::EmitThunks(GlobalDecl GD) @@ -484,14 +461,18 @@ void CodeGenVTables::EmitThunks(GlobalDecl GD)    if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)      return; -  const VTableContext::ThunkInfoVectorTy *ThunkInfoVector = -    VTContext.getThunkInfo(MD); +  const VTableContextBase::ThunkInfoVectorTy *ThunkInfoVector; +  if (MicrosoftVTContext.isValid()) { +    ThunkInfoVector = MicrosoftVTContext->getThunkInfo(GD); +  } else { +    ThunkInfoVector = ItaniumVTContext.getThunkInfo(GD); +  } +    if (!ThunkInfoVector)      return;    for (unsigned I = 0, E = ThunkInfoVector->size(); I != E; ++I) -    EmitThunk(GD, (*ThunkInfoVector)[I], -              /*UseAvailableExternallyLinkage=*/false); +    emitThunk(GD, (*ThunkInfoVector)[I], /*ForVTable=*/false);  }  llvm::Constant * @@ -586,7 +567,7 @@ CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD,              VTableThunks[NextVTableThunkIndex].first == I) {            const ThunkInfo &Thunk = VTableThunks[NextVTableThunkIndex].second; -          MaybeEmitThunkAvailableExternally(GD, Thunk); +          maybeEmitThunkForVTable(GD, Thunk);            Init = CGM.GetAddrOfThunk(GD, Thunk);            NextVTableThunkIndex++; @@ -613,63 +594,18 @@ CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD,    return llvm::ConstantArray::get(ArrayType, Inits);  } -llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) { -  llvm::GlobalVariable *&VTable = VTables[RD]; -  if (VTable) -    return VTable; - -  // Queue up this v-table for possible deferred emission. -  CGM.addDeferredVTable(RD); - -  SmallString<256> OutName; -  llvm::raw_svector_ostream Out(OutName); -  CGM.getCXXABI().getMangleContext().mangleCXXVTable(RD, Out); -  Out.flush(); -  StringRef Name = OutName.str(); - -  llvm::ArrayType *ArrayType =  -    llvm::ArrayType::get(CGM.Int8PtrTy, -                        VTContext.getVTableLayout(RD).getNumVTableComponents()); - -  VTable = -    CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType,  -                                          llvm::GlobalValue::ExternalLinkage); -  VTable->setUnnamedAddr(true); -  return VTable; -} - -void -CodeGenVTables::EmitVTableDefinition(llvm::GlobalVariable *VTable, -                                     llvm::GlobalVariable::LinkageTypes Linkage, -                                     const CXXRecordDecl *RD) { -  const VTableLayout &VTLayout = VTContext.getVTableLayout(RD); - -  // Create and set the initializer. -  llvm::Constant *Init =  -    CreateVTableInitializer(RD, -                            VTLayout.vtable_component_begin(), -                            VTLayout.getNumVTableComponents(), -                            VTLayout.vtable_thunk_begin(), -                            VTLayout.getNumVTableThunks()); -  VTable->setInitializer(Init); -   -  // Set the correct linkage. -  VTable->setLinkage(Linkage); -   -  // Set the right visibility. -  CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForVTable); -} -  llvm::GlobalVariable *  CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,                                         const BaseSubobject &Base,                                         bool BaseIsVirtual,                                      llvm::GlobalVariable::LinkageTypes Linkage,                                        VTableAddressPointsMapTy& AddressPoints) { +  if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) +    DI->completeClassData(Base.getBase()); +    OwningPtr<VTableLayout> VTLayout( -    VTContext.createConstructionVTableLayout(Base.getBase(), -                                             Base.getBaseOffset(), -                                             BaseIsVirtual, RD)); +      ItaniumVTContext.createConstructionVTableLayout( +          Base.getBase(), Base.getBaseOffset(), BaseIsVirtual, RD));    // Add the address points.    AddressPoints = VTLayout->getAddressPoints(); @@ -677,9 +613,9 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,    // Get the mangled construction vtable name.    SmallString<256> OutName;    llvm::raw_svector_ostream Out(OutName); -  CGM.getCXXABI().getMangleContext(). -    mangleCXXCtorVTable(RD, Base.getBaseOffset().getQuantity(), Base.getBase(),  -                        Out); +  cast<ItaniumMangleContext>(CGM.getCXXABI().getMangleContext()) +      .mangleCXXCtorVTable(RD, Base.getBaseOffset().getQuantity(), +                           Base.getBase(), Out);    Out.flush();    StringRef Name = OutName.str(); @@ -719,7 +655,7 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,  /// Note that we only call this at the end of the translation unit.  llvm::GlobalVariable::LinkageTypes   CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { -  if (RD->getLinkage() != ExternalLinkage) +  if (!RD->isExternallyVisible())      return llvm::GlobalVariable::InternalLinkage;    // We're at the end of the translation unit, so the current key @@ -734,12 +670,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {      switch (keyFunction->getTemplateSpecializationKind()) {        case TSK_Undeclared:        case TSK_ExplicitSpecialization: -        // When compiling with optimizations turned on, we emit all vtables, -        // even if the key function is not defined in the current translation -        // unit. If this is the case, use available_externally linkage. -        if (!def && CodeGenOpts.OptimizationLevel) -          return llvm::GlobalVariable::AvailableExternallyLinkage; - +        assert(def && "Should not have been asked to emit this");          if (keyFunction->isInlined())            return !Context.getLangOpts().AppleKext ?                     llvm::GlobalVariable::LinkOnceODRLinkage : @@ -758,9 +689,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {                   llvm::Function::InternalLinkage;        case TSK_ExplicitInstantiationDeclaration: -        return !Context.getLangOpts().AppleKext ? -                 llvm::GlobalVariable::AvailableExternallyLinkage : -                 llvm::Function::InternalLinkage; +        llvm_unreachable("Should not have been asked to emit this");      }    } @@ -776,7 +705,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {      return llvm::GlobalVariable::LinkOnceODRLinkage;    case TSK_ExplicitInstantiationDeclaration: -    return llvm::GlobalVariable::AvailableExternallyLinkage; +    llvm_unreachable("Should not have been asked to emit this");    case TSK_ExplicitInstantiationDefinition:        return llvm::GlobalVariable::WeakODRLinkage; @@ -803,35 +732,13 @@ void CodeGenModule::EmitVTable(CXXRecordDecl *theClass, bool isRequired) {  void   CodeGenVTables::GenerateClassData(const CXXRecordDecl *RD) { -  // First off, check whether we've already emitted the v-table and -  // associated stuff. -  llvm::GlobalVariable *VTable = GetAddrOfVTable(RD); -  if (VTable->hasInitializer()) -    return; - -  llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD); -  EmitVTableDefinition(VTable, Linkage, RD); +  if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) +    DI->completeClassData(RD); -  if (RD->getNumVBases()) { -    if (!CGM.getTarget().getCXXABI().isMicrosoft()) { -      llvm::GlobalVariable *VTT = GetAddrOfVTT(RD); -      EmitVTTDefinition(VTT, Linkage, RD); -    } else { -      // FIXME: Emit vbtables here. -    } -  } +  if (RD->getNumVBases()) +    CGM.getCXXABI().emitVirtualInheritanceTables(RD); -  // If this is the magic class __cxxabiv1::__fundamental_type_info, -  // we will emit the typeinfo for the fundamental types. This is the -  // same behaviour as GCC. -  const DeclContext *DC = RD->getDeclContext(); -  if (RD->getIdentifier() && -      RD->getIdentifier()->isStr("__fundamental_type_info") && -      isa<NamespaceDecl>(DC) && -      cast<NamespaceDecl>(DC)->getIdentifier() && -      cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") && -      DC->getParent()->isTranslationUnit()) -    CGM.EmitFundamentalRTTIDescriptors(); +  CGM.getCXXABI().emitVTableDefinitions(*this, RD);  }  /// At this point in the translation unit, does it appear that can we @@ -875,16 +782,6 @@ bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) {  /// we define that v-table?  static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM,                                                     const CXXRecordDecl *RD) { -  // If we're building with optimization, we always emit v-tables -  // since that allows for virtual function calls to be devirtualized. -  // If the v-table is defined strongly elsewhere, this definition -  // will be emitted available_externally. -  // -  // However, we don't want to do this in -fapple-kext mode, because -  // kext mode does not permit devirtualization. -  if (CGM.getCodeGenOpts().OptimizationLevel && !CGM.getLangOpts().AppleKext) -    return true; -    return !CGM.getVTables().isVTableExternal(RD);  } diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h index bd3bdb13583d5..e8cd55eed80a6 100644 --- a/lib/CodeGen/CGVTables.h +++ b/lib/CodeGen/CGVTables.h @@ -31,10 +31,10 @@ namespace CodeGen {  class CodeGenVTables {    CodeGenModule &CGM; -  VTableContext VTContext; - -  /// VTables - All the vtables which have been defined. -  llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables; +  // FIXME: Consider moving ItaniumVTContext and MicrosoftVTContext into +  // respective CXXABI classes? +  ItaniumVTableContext ItaniumVTContext; +  OwningPtr<MicrosoftVTableContext> MicrosoftVTContext;    /// VTableAddressPointsMapTy - Address points for a single vtable.    typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy; @@ -52,16 +52,14 @@ class CodeGenVTables {    /// indices.    SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices; -  /// EmitThunk - Emit a single thunk. -  void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk,  -                 bool UseAvailableExternallyLinkage); +  /// emitThunk - Emit a single thunk. +  void emitThunk(GlobalDecl GD, const ThunkInfo &Thunk, bool ForVTable); -  /// MaybeEmitThunkAvailableExternally - Try to emit the given thunk with -  /// available_externally linkage to allow for inlining of thunks. -  /// This will be done iff optimizations are enabled and the member function -  /// doesn't contain any incomplete types. -  void MaybeEmitThunkAvailableExternally(GlobalDecl GD, const ThunkInfo &Thunk); +  /// maybeEmitThunkForVTable - Emit the given thunk for the vtable if needed by +  /// the ABI. +  void maybeEmitThunkForVTable(GlobalDecl GD, const ThunkInfo &Thunk); +public:    /// CreateVTableInitializer - Create a vtable initializer for the given record    /// decl.    /// \param Components - The vtable components; this is really an array of @@ -72,15 +70,13 @@ class CodeGenVTables {                                  const VTableLayout::VTableThunkTy *VTableThunks,                                            unsigned NumVTableThunks); -public:    CodeGenVTables(CodeGenModule &CGM); -  VTableContext &getVTableContext() { return VTContext; } +  ItaniumVTableContext &getItaniumVTableContext() { return ItaniumVTContext; } -  /// needsVTTParameter - Return whether the given global decl needs a VTT -  /// parameter, which it does if it's a base constructor or destructor with -  /// virtual bases. -  static bool needsVTTParameter(GlobalDecl GD); +  MicrosoftVTableContext &getMicrosoftVTableContext() { +    return *MicrosoftVTContext.get(); +  }    /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the    /// given record decl. @@ -95,14 +91,6 @@ public:    /// class decl.    uint64_t getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD); -  /// GetAddrOfVTable - Get the address of the vtable for the given record decl. -  llvm::GlobalVariable *GetAddrOfVTable(const CXXRecordDecl *RD); - -  /// EmitVTableDefinition - Emit the definition of the given vtable. -  void EmitVTableDefinition(llvm::GlobalVariable *VTable, -                            llvm::GlobalVariable::LinkageTypes Linkage, -                            const CXXRecordDecl *RD); -      /// GenerateConstructionVTable - Generate a construction vtable for the given     /// base subobject.    llvm::GlobalVariable * diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index b625b866c072b..da2a03437d3d6 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -381,23 +381,11 @@ class AggValueSlot {    /// evaluating an expression which constructs such an object.    bool AliasedFlag : 1; -  /// ValueOfAtomicFlag - This is set to true if the slot is the value -  /// subobject of an object the size of an _Atomic(T).  The specific -  /// guarantees this makes are: -  ///   - the address is guaranteed to be a getelementptr into the -  ///     padding struct and -  ///   - it is okay to store something the width of an _Atomic(T) -  ///     into the address. -  /// Tracking this allows us to avoid some obviously unnecessary -  /// memcpys. -  bool ValueOfAtomicFlag : 1; -  public:    enum IsAliased_t { IsNotAliased, IsAliased };    enum IsDestructed_t { IsNotDestructed, IsDestructed };    enum IsZeroed_t { IsNotZeroed, IsZeroed };    enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers }; -  enum IsValueOfAtomic_t { IsNotValueOfAtomic, IsValueOfAtomic };    /// ignored - Returns an aggregate value slot indicating that the    /// aggregate value is being ignored. @@ -421,9 +409,7 @@ public:                                IsDestructed_t isDestructed,                                NeedsGCBarriers_t needsGC,                                IsAliased_t isAliased, -                              IsZeroed_t isZeroed = IsNotZeroed, -                              IsValueOfAtomic_t isValueOfAtomic -                                = IsNotValueOfAtomic) { +                              IsZeroed_t isZeroed = IsNotZeroed) {      AggValueSlot AV;      AV.Addr = addr;      AV.Alignment = align.getQuantity(); @@ -432,7 +418,6 @@ public:      AV.ObjCGCFlag = needsGC;      AV.ZeroedFlag = isZeroed;      AV.AliasedFlag = isAliased; -    AV.ValueOfAtomicFlag = isValueOfAtomic;      return AV;    } @@ -440,12 +425,9 @@ public:                                  IsDestructed_t isDestructed,                                  NeedsGCBarriers_t needsGC,                                  IsAliased_t isAliased, -                                IsZeroed_t isZeroed = IsNotZeroed, -                                IsValueOfAtomic_t isValueOfAtomic -                                  = IsNotValueOfAtomic) { +                                IsZeroed_t isZeroed = IsNotZeroed) {      return forAddr(LV.getAddress(), LV.getAlignment(), -                   LV.getQuals(), isDestructed, needsGC, isAliased, isZeroed, -                   isValueOfAtomic); +                   LV.getQuals(), isDestructed, needsGC, isAliased, isZeroed);    }    IsDestructed_t isExternallyDestructed() const { @@ -477,12 +459,6 @@ public:      return Addr;    } -  IsValueOfAtomic_t isValueOfAtomic() const { -    return IsValueOfAtomic_t(ValueOfAtomicFlag); -  } - -  llvm::Value *getPaddedAtomicAddr() const; -    bool isIgnored() const {      return Addr == 0;    } diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt index 9ca2295a9229e..83dbbf0d34609 100644 --- a/lib/CodeGen/CMakeLists.txt +++ b/lib/CodeGen/CMakeLists.txt @@ -41,6 +41,7 @@ add_clang_library(clangCodeGen    CGStmt.cpp    CGVTables.cpp    CGVTT.cpp +  CodeGenABITypes.cpp    CodeGenAction.cpp    CodeGenFunction.cpp    CodeGenModule.cpp @@ -48,6 +49,7 @@ add_clang_library(clangCodeGen    CodeGenTypes.cpp    ItaniumCXXABI.cpp    MicrosoftCXXABI.cpp +  MicrosoftVBTables.cpp    ModuleBuilder.cpp    TargetInfo.cpp    ) diff --git a/lib/CodeGen/CodeGenABITypes.cpp b/lib/CodeGen/CodeGenABITypes.cpp new file mode 100644 index 0000000000000..18c836cf2f4ca --- /dev/null +++ b/lib/CodeGen/CodeGenABITypes.cpp @@ -0,0 +1,69 @@ +//==--- CodeGenABITypes.cpp - Convert Clang types to LLVM types for ABI ----==// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// CodeGenABITypes is a simple interface for getting LLVM types for +// the parameters and the return value of a function given the Clang +// types. +// +// The class is implemented as a public wrapper around the private +// CodeGenTypes class in lib/CodeGen. +// +//===----------------------------------------------------------------------===// + +#include "clang/CodeGen/CodeGenABITypes.h" + +#include "clang/CodeGen/CGFunctionInfo.h" +#include "CodeGenModule.h" + +using namespace clang; +using namespace CodeGen; + +CodeGenABITypes::CodeGenABITypes(ASTContext &C, +                                 const CodeGenOptions &CodeGenOpts, +                                 llvm::Module &M, +                                 const llvm::DataLayout &TD, +                                 DiagnosticsEngine &Diags) +  : CGM(new CodeGen::CodeGenModule(C, CodeGenOpts, M, TD, Diags)) { +} + +CodeGenABITypes::~CodeGenABITypes() +{ +  delete CGM; +} + +const CGFunctionInfo & +CodeGenABITypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD, +                                                 QualType receiverType) { +  return CGM->getTypes().arrangeObjCMessageSendSignature(MD, receiverType); +} + +const CGFunctionInfo & +CodeGenABITypes::arrangeFreeFunctionType(CanQual<FunctionProtoType> Ty) { +  return CGM->getTypes().arrangeFreeFunctionType(Ty); +} + +const CGFunctionInfo & +CodeGenABITypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> Ty) { +  return CGM->getTypes().arrangeFreeFunctionType(Ty); +} + +const CGFunctionInfo & +CodeGenABITypes::arrangeCXXMethodType(const CXXRecordDecl *RD, +                                      const FunctionProtoType *FTP) { +  return CGM->getTypes().arrangeCXXMethodType(RD, FTP); +} + +const CGFunctionInfo & +CodeGenABITypes::arrangeLLVMFunctionInfo(CanQualType returnType, +                                         llvm::ArrayRef<CanQualType> argTypes, +                                         FunctionType::ExtInfo info, +                                         RequiredArgs args) { +  return CGM->getTypes().arrangeLLVMFunctionInfo(returnType, argTypes, +                                                info, args); +} diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp index 679cfeb6ed3c4..3072204c9b66d 100644 --- a/lib/CodeGen/CodeGenAction.cpp +++ b/lib/CodeGen/CodeGenAction.cpp @@ -171,6 +171,10 @@ namespace clang {        Gen->HandleTagDeclDefinition(D);      } +    virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) { +      Gen->HandleTagDeclRequiredDefinition(D); +    } +      virtual void CompleteTentativeDefinition(VarDecl *D) {        Gen->CompleteTentativeDefinition(D);      } @@ -179,6 +183,19 @@ namespace clang {        Gen->HandleVTable(RD, DefinitionRequired);      } +    virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) { +      Gen->HandleLinkerOptionPragma(Opts); +    } + +    virtual void HandleDetectMismatch(llvm::StringRef Name, +                                      llvm::StringRef Value) { +      Gen->HandleDetectMismatch(Name, Value); +    } + +    virtual void HandleDependentLibrary(llvm::StringRef Opts) { +      Gen->HandleDependentLibrary(Opts); +    } +      static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context,                                       unsigned LocCookie) {        SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie); diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 75c60edbba531..ce1b44559dcc7 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -16,12 +16,14 @@  #include "CGCXXABI.h"  #include "CGDebugInfo.h"  #include "CodeGenModule.h" +#include "TargetInfo.h"  #include "clang/AST/ASTContext.h"  #include "clang/AST/Decl.h"  #include "clang/AST/DeclCXX.h"  #include "clang/AST/StmtCXX.h"  #include "clang/Basic/OpenCL.h"  #include "clang/Basic/TargetInfo.h" +#include "clang/CodeGen/CGFunctionInfo.h"  #include "clang/Frontend/CodeGenOptions.h"  #include "llvm/IR/DataLayout.h"  #include "llvm/IR/Intrinsics.h" @@ -31,25 +33,23 @@ using namespace clang;  using namespace CodeGen;  CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) -  : CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()), -    Builder(cgm.getModule().getContext()), -    SanitizePerformTypeCheck(CGM.getSanOpts().Null | -                             CGM.getSanOpts().Alignment | -                             CGM.getSanOpts().ObjectSize | -                             CGM.getSanOpts().Vptr), -    SanOpts(&CGM.getSanOpts()), -    AutoreleaseResult(false), BlockInfo(0), BlockPointer(0), -    LambdaThisCaptureField(0), NormalCleanupDest(0), NextCleanupDestIndex(1), -    FirstBlockInfo(0), EHResumeBlock(0), ExceptionSlot(0), EHSelectorSlot(0), -    DebugInfo(0), DisableDebugInfo(false), CalleeWithThisReturn(0), -    DidCallStackSave(false), -    IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0), -    NumReturnExprs(0), NumSimpleReturnExprs(0), -    CXXABIThisDecl(0), CXXABIThisValue(0), CXXThisValue(0), -    CXXDefaultInitExprThis(0), -    CXXStructorImplicitParamDecl(0), CXXStructorImplicitParamValue(0), -    OutermostConditional(0), CurLexicalScope(0), TerminateLandingPad(0), -    TerminateHandler(0), TrapBB(0) { +    : CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()), +      Builder(cgm.getModule().getContext()), CapturedStmtInfo(0), +      SanitizePerformTypeCheck(CGM.getSanOpts().Null | +                               CGM.getSanOpts().Alignment | +                               CGM.getSanOpts().ObjectSize | +                               CGM.getSanOpts().Vptr), +      SanOpts(&CGM.getSanOpts()), AutoreleaseResult(false), BlockInfo(0), +      BlockPointer(0), LambdaThisCaptureField(0), NormalCleanupDest(0), +      NextCleanupDestIndex(1), FirstBlockInfo(0), EHResumeBlock(0), +      ExceptionSlot(0), EHSelectorSlot(0), DebugInfo(CGM.getModuleDebugInfo()), +      DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(0), +      SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0), NumReturnExprs(0), +      NumSimpleReturnExprs(0), CXXABIThisDecl(0), CXXABIThisValue(0), +      CXXThisValue(0), CXXDefaultInitExprThis(0), +      CXXStructorImplicitParamDecl(0), CXXStructorImplicitParamValue(0), +      OutermostConditional(0), CurLexicalScope(0), TerminateLandingPad(0), +      TerminateHandler(0), TrapBB(0) {    if (!suppressNewContext)      CGM.getCXXABI().getMangleContext().startNewFunction(); @@ -64,6 +64,8 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)  }  CodeGenFunction::~CodeGenFunction() { +  assert(LifetimeExtendedCleanupStack.empty() && "failed to emit a cleanup"); +    // If there are any unclaimed block infos, go ahead and destroy them    // now.  This can happen if IR-gen gets clever and skips evaluating    // something. @@ -189,15 +191,23 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {           "mismatched push/pop in break/continue stack!");    bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0 -    && NumSimpleReturnExprs == NumReturnExprs; -  // If the function contains only a simple return statement, the -  // cleanup code may become the first breakpoint in the function. To -  // be safe, set the debug location for it to the location of the -  // return statement.  Otherwise point it to end of the function's -  // lexical scope. +    && NumSimpleReturnExprs == NumReturnExprs +    && ReturnBlock.getBlock()->use_empty(); +  // Usually the return expression is evaluated before the cleanup +  // code.  If the function contains only a simple return statement, +  // such as a constant, the location before the cleanup code becomes +  // the last useful breakpoint in the function, because the simple +  // return expression will be evaluated after the cleanup code. To be +  // safe, set the debug location for cleanup code to the location of +  // the return statement.  Otherwise the cleanup code should be at the +  // end of the function's lexical scope. +  // +  // If there are multiple branches to the return block, the branch +  // instructions will get the location of the return statements and +  // all will be fine.    if (CGDebugInfo *DI = getDebugInfo()) {      if (OnlySimpleReturnStmts) -       DI->EmitLocation(Builder, LastStopPoint); +      DI->EmitLocation(Builder, LastStopPoint);      else        DI->EmitLocation(Builder, EndLoc);    } @@ -208,7 +218,7 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {    // edges will be *really* confused.    bool EmitRetDbgLoc = true;    if (EHStack.stable_begin() != PrologueCleanupDepth) { -    PopCleanupBlocks(PrologueCleanupDepth, EndLoc); +    PopCleanupBlocks(PrologueCleanupDepth);      // Make sure the line table doesn't jump back into the body for      // the ret after it's been at EndLoc. @@ -230,7 +240,7 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {      DI->EmitFunctionEnd(Builder);    } -  EmitFunctionEpilog(*CurFnInfo, EmitRetDbgLoc); +  EmitFunctionEpilog(*CurFnInfo, EmitRetDbgLoc, EndLoc);    EmitEndEHSpec(CurCodeDecl);    assert(EHStack.empty() && @@ -511,6 +521,22 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,        EmitOpenCLKernelMetadata(FD, Fn);    } +  // If we are checking function types, emit a function type signature as +  // prefix data. +  if (getLangOpts().CPlusPlus && SanOpts->Function) { +    if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) { +      if (llvm::Constant *PrefixSig = +              CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) { +        llvm::Constant *FTRTTIConst = +            CGM.GetAddrOfRTTIDescriptor(FD->getType(), /*ForEH=*/true); +        llvm::Constant *PrefixStructElems[] = { PrefixSig, FTRTTIConst }; +        llvm::Constant *PrefixStructConst = +            llvm::ConstantStruct::getAnon(PrefixStructElems, /*Packed=*/true); +        Fn->setPrefixData(PrefixStructConst); +      } +    } +  } +    llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn);    // Create a marker to make it easy to insert allocas into the entryblock @@ -583,7 +609,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,        if (LambdaThisCaptureField) {          // If this lambda captures this, load it.          LValue ThisLValue = EmitLValueForLambdaField(LambdaThisCaptureField); -        CXXThisValue = EmitLoadOfLValue(ThisLValue).getScalarVal(); +        CXXThisValue = EmitLoadOfLValue(ThisLValue, +                                        SourceLocation()).getScalarVal();        }      } else {        // Not in a lambda; just use 'this' from the method. @@ -616,13 +643,12 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,      DI->EmitLocation(Builder, StartLoc);  } -void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args) { -  const FunctionDecl *FD = cast<FunctionDecl>(CurGD.getDecl()); -  assert(FD->getBody()); -  if (const CompoundStmt *S = dyn_cast<CompoundStmt>(FD->getBody())) +void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args, +                                       const Stmt *Body) { +  if (const CompoundStmt *S = dyn_cast<CompoundStmt>(Body))      EmitCompoundStmtWithoutScope(*S);    else -    EmitStmt(FD->getBody()); +    EmitStmt(Body);  }  /// Tries to mark the given function nounwind based on the @@ -645,30 +671,42 @@ static void TryMarkNoThrow(llvm::Function *F) {    F->setDoesNotThrow();  } +static void EmitSizedDeallocationFunction(CodeGenFunction &CGF, +                                          const FunctionDecl *UnsizedDealloc) { +  // This is a weak discardable definition of the sized deallocation function. +  CGF.CurFn->setLinkage(llvm::Function::LinkOnceAnyLinkage); + +  // Call the unsized deallocation function and forward the first argument +  // unchanged. +  llvm::Constant *Unsized = CGF.CGM.GetAddrOfFunction(UnsizedDealloc); +  CGF.Builder.CreateCall(Unsized, &*CGF.CurFn->arg_begin()); +} +  void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,                                     const CGFunctionInfo &FnInfo) {    const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());    // Check if we should generate debug info for this function. -  if (!FD->hasAttr<NoDebugAttr>()) -    maybeInitializeDebugInfo(); +  if (FD->hasAttr<NoDebugAttr>()) +    DebugInfo = NULL; // disable debug info indefinitely for this function    FunctionArgList Args;    QualType ResTy = FD->getResultType();    CurGD = GD; -  if (isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isInstance()) +  const CXXMethodDecl *MD; +  if ((MD = dyn_cast<CXXMethodDecl>(FD)) && MD->isInstance()) { +    if (CGM.getCXXABI().HasThisReturn(GD)) +      ResTy = MD->getThisType(getContext());      CGM.getCXXABI().BuildInstanceFunctionParams(*this, ResTy, Args); +  }    for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i)      Args.push_back(FD->getParamDecl(i));    SourceRange BodyRange;    if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange(); - -  // CalleeWithThisReturn keeps track of the last callee inside this function -  // that returns 'this'. Before starting the function, we set it to null. -  CalleeWithThisReturn = 0; +  CurEHLocation = BodyRange.getEnd();    // Emit the standard function prologue.    StartFunction(GD, ResTy, Fn, FnInfo, Args, BodyRange.getBegin()); @@ -689,17 +727,24 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,      EmitLambdaToBlockPointerBody(Args);    } else if (isa<CXXMethodDecl>(FD) &&               cast<CXXMethodDecl>(FD)->isLambdaStaticInvoker()) { -    // The lambda "__invoke" function is special, because it forwards or +    // The lambda static invoker function is special, because it forwards or      // clones the body of the function call operator (but is actually static).      EmitLambdaStaticInvokeFunction(cast<CXXMethodDecl>(FD));    } else if (FD->isDefaulted() && isa<CXXMethodDecl>(FD) && -             cast<CXXMethodDecl>(FD)->isCopyAssignmentOperator()) { +             (cast<CXXMethodDecl>(FD)->isCopyAssignmentOperator() || +              cast<CXXMethodDecl>(FD)->isMoveAssignmentOperator())) {      // Implicit copy-assignment gets the same special treatment as implicit      // copy-constructors.      emitImplicitAssignmentOperatorBody(Args); -  } -  else -    EmitFunctionBody(Args); +  } else if (Stmt *Body = FD->getBody()) { +    EmitFunctionBody(Args, Body); +  } else if (FunctionDecl *UnsizedDealloc = +                 FD->getCorrespondingUnsizedGlobalDeallocationFunction()) { +    // Global sized deallocation functions get an implicit weak definition if +    // they don't have an explicit definition. +    EmitSizedDeallocationFunction(*this, UnsizedDealloc); +  } else +    llvm_unreachable("no definition for emitted function");    // C++11 [stmt.return]p2:    //   Flowing off the end of a function [...] results in undefined behavior in @@ -721,9 +766,6 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,    // Emit the standard function epilogue.    FinishFunction(BodyRange.getEnd()); -  // CalleeWithThisReturn keeps track of the last callee inside this function -  // that returns 'this'. After finishing the function, we set it to null. -  CalleeWithThisReturn = 0;    // If we haven't marked the function nothrow through other means, do    // a quick pass now to see if we can. @@ -945,9 +987,8 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,  /// ErrorUnsupported - Print out an error that codegen doesn't support the  /// specified stmt yet. -void CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type, -                                       bool OmitOnError) { -  CGM.ErrorUnsupported(S, Type, OmitOnError); +void CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type) { +  CGM.ErrorUnsupported(S, Type);  }  /// emitNonZeroVLAInit - Emit the "zero" initialization of a @@ -1267,6 +1308,10 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {      case Type::ObjCObjectPointer:        llvm_unreachable("type class is never variably-modified!"); +    case Type::Decayed: +      type = cast<DecayedType>(ty)->getPointeeType(); +      break; +      case Type::Pointer:        type = cast<PointerType>(ty)->getPointeeType();        break; @@ -1338,6 +1383,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {      case Type::UnaryTransform:      case Type::Attributed:      case Type::SubstTemplateTypeParm: +    case Type::PackExpansion:        // Keep walking after single level desugaring.        type = type.getSingleStepDesugaredType(getContext());        break; @@ -1447,3 +1493,5 @@ llvm::Value *CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D,    return V;  } + +CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() { } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index ff74c15c38c3a..db291e3b1ddd1 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -17,12 +17,14 @@  #include "CGBuilder.h"  #include "CGDebugInfo.h"  #include "CGValue.h" +#include "EHScopeStack.h"  #include "CodeGenModule.h"  #include "clang/AST/CharUnits.h"  #include "clang/AST/ExprCXX.h"  #include "clang/AST/ExprObjC.h"  #include "clang/AST/Type.h"  #include "clang/Basic/ABI.h" +#include "clang/Basic/CapturedStmt.h"  #include "clang/Basic/TargetInfo.h"  #include "clang/Frontend/CodeGenOptions.h"  #include "llvm/ADT/ArrayRef.h" @@ -89,457 +91,6 @@ enum TypeEvaluationKind {    TEK_Aggregate  }; -/// A branch fixup.  These are required when emitting a goto to a -/// label which hasn't been emitted yet.  The goto is optimistically -/// emitted as a branch to the basic block for the label, and (if it -/// occurs in a scope with non-trivial cleanups) a fixup is added to -/// the innermost cleanup.  When a (normal) cleanup is popped, any -/// unresolved fixups in that scope are threaded through the cleanup. -struct BranchFixup { -  /// The block containing the terminator which needs to be modified -  /// into a switch if this fixup is resolved into the current scope. -  /// If null, LatestBranch points directly to the destination. -  llvm::BasicBlock *OptimisticBranchBlock; - -  /// The ultimate destination of the branch. -  /// -  /// This can be set to null to indicate that this fixup was -  /// successfully resolved. -  llvm::BasicBlock *Destination; - -  /// The destination index value. -  unsigned DestinationIndex; - -  /// The initial branch of the fixup. -  llvm::BranchInst *InitialBranch; -}; - -template <class T> struct InvariantValue { -  typedef T type; -  typedef T saved_type; -  static bool needsSaving(type value) { return false; } -  static saved_type save(CodeGenFunction &CGF, type value) { return value; } -  static type restore(CodeGenFunction &CGF, saved_type value) { return value; } -}; - -/// A metaprogramming class for ensuring that a value will dominate an -/// arbitrary position in a function. -template <class T> struct DominatingValue : InvariantValue<T> {}; - -template <class T, bool mightBeInstruction = -            llvm::is_base_of<llvm::Value, T>::value && -            !llvm::is_base_of<llvm::Constant, T>::value && -            !llvm::is_base_of<llvm::BasicBlock, T>::value> -struct DominatingPointer; -template <class T> struct DominatingPointer<T,false> : InvariantValue<T*> {}; -// template <class T> struct DominatingPointer<T,true> at end of file - -template <class T> struct DominatingValue<T*> : DominatingPointer<T> {}; - -enum CleanupKind { -  EHCleanup = 0x1, -  NormalCleanup = 0x2, -  NormalAndEHCleanup = EHCleanup | NormalCleanup, - -  InactiveCleanup = 0x4, -  InactiveEHCleanup = EHCleanup | InactiveCleanup, -  InactiveNormalCleanup = NormalCleanup | InactiveCleanup, -  InactiveNormalAndEHCleanup = NormalAndEHCleanup | InactiveCleanup -}; - -/// A stack of scopes which respond to exceptions, including cleanups -/// and catch blocks. -class EHScopeStack { -public: -  /// A saved depth on the scope stack.  This is necessary because -  /// pushing scopes onto the stack invalidates iterators. -  class stable_iterator { -    friend class EHScopeStack; - -    /// Offset from StartOfData to EndOfBuffer. -    ptrdiff_t Size; - -    stable_iterator(ptrdiff_t Size) : Size(Size) {} - -  public: -    static stable_iterator invalid() { return stable_iterator(-1); } -    stable_iterator() : Size(-1) {} - -    bool isValid() const { return Size >= 0; } - -    /// Returns true if this scope encloses I. -    /// Returns false if I is invalid. -    /// This scope must be valid. -    bool encloses(stable_iterator I) const { return Size <= I.Size; } - -    /// Returns true if this scope strictly encloses I: that is, -    /// if it encloses I and is not I. -    /// Returns false is I is invalid. -    /// This scope must be valid. -    bool strictlyEncloses(stable_iterator I) const { return Size < I.Size; } - -    friend bool operator==(stable_iterator A, stable_iterator B) { -      return A.Size == B.Size; -    } -    friend bool operator!=(stable_iterator A, stable_iterator B) { -      return A.Size != B.Size; -    } -  }; - -  /// Information for lazily generating a cleanup.  Subclasses must be -  /// POD-like: cleanups will not be destructed, and they will be -  /// allocated on the cleanup stack and freely copied and moved -  /// around. -  /// -  /// Cleanup implementations should generally be declared in an -  /// anonymous namespace. -  class Cleanup { -    // Anchor the construction vtable. -    virtual void anchor(); -  public: -    /// Generation flags. -    class Flags { -      enum { -        F_IsForEH             = 0x1, -        F_IsNormalCleanupKind = 0x2, -        F_IsEHCleanupKind     = 0x4 -      }; -      unsigned flags; - -    public: -      Flags() : flags(0) {} - -      /// isForEH - true if the current emission is for an EH cleanup. -      bool isForEHCleanup() const { return flags & F_IsForEH; } -      bool isForNormalCleanup() const { return !isForEHCleanup(); } -      void setIsForEHCleanup() { flags |= F_IsForEH; } - -      bool isNormalCleanupKind() const { return flags & F_IsNormalCleanupKind; } -      void setIsNormalCleanupKind() { flags |= F_IsNormalCleanupKind; } - -      /// isEHCleanupKind - true if the cleanup was pushed as an EH -      /// cleanup. -      bool isEHCleanupKind() const { return flags & F_IsEHCleanupKind; } -      void setIsEHCleanupKind() { flags |= F_IsEHCleanupKind; } -    }; - -    // Provide a virtual destructor to suppress a very common warning -    // that unfortunately cannot be suppressed without this.  Cleanups -    // should not rely on this destructor ever being called. -    virtual ~Cleanup() {} - -    /// Emit the cleanup.  For normal cleanups, this is run in the -    /// same EH context as when the cleanup was pushed, i.e. the -    /// immediately-enclosing context of the cleanup scope.  For -    /// EH cleanups, this is run in a terminate context. -    /// -    // \param flags cleanup kind. -    virtual void Emit(CodeGenFunction &CGF, Flags flags) = 0; -  }; - -  /// ConditionalCleanupN stores the saved form of its N parameters, -  /// then restores them and performs the cleanup. -  template <class T, class A0> -  class ConditionalCleanup1 : public Cleanup { -    typedef typename DominatingValue<A0>::saved_type A0_saved; -    A0_saved a0_saved; - -    void Emit(CodeGenFunction &CGF, Flags flags) { -      A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved); -      T(a0).Emit(CGF, flags); -    } - -  public: -    ConditionalCleanup1(A0_saved a0) -      : a0_saved(a0) {} -  }; - -  template <class T, class A0, class A1> -  class ConditionalCleanup2 : public Cleanup { -    typedef typename DominatingValue<A0>::saved_type A0_saved; -    typedef typename DominatingValue<A1>::saved_type A1_saved; -    A0_saved a0_saved; -    A1_saved a1_saved; - -    void Emit(CodeGenFunction &CGF, Flags flags) { -      A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved); -      A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved); -      T(a0, a1).Emit(CGF, flags); -    } - -  public: -    ConditionalCleanup2(A0_saved a0, A1_saved a1) -      : a0_saved(a0), a1_saved(a1) {} -  }; - -  template <class T, class A0, class A1, class A2> -  class ConditionalCleanup3 : public Cleanup { -    typedef typename DominatingValue<A0>::saved_type A0_saved; -    typedef typename DominatingValue<A1>::saved_type A1_saved; -    typedef typename DominatingValue<A2>::saved_type A2_saved; -    A0_saved a0_saved; -    A1_saved a1_saved; -    A2_saved a2_saved; -     -    void Emit(CodeGenFunction &CGF, Flags flags) { -      A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved); -      A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved); -      A2 a2 = DominatingValue<A2>::restore(CGF, a2_saved); -      T(a0, a1, a2).Emit(CGF, flags); -    } -     -  public: -    ConditionalCleanup3(A0_saved a0, A1_saved a1, A2_saved a2) -      : a0_saved(a0), a1_saved(a1), a2_saved(a2) {} -  }; - -  template <class T, class A0, class A1, class A2, class A3> -  class ConditionalCleanup4 : public Cleanup { -    typedef typename DominatingValue<A0>::saved_type A0_saved; -    typedef typename DominatingValue<A1>::saved_type A1_saved; -    typedef typename DominatingValue<A2>::saved_type A2_saved; -    typedef typename DominatingValue<A3>::saved_type A3_saved; -    A0_saved a0_saved; -    A1_saved a1_saved; -    A2_saved a2_saved; -    A3_saved a3_saved; -     -    void Emit(CodeGenFunction &CGF, Flags flags) { -      A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved); -      A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved); -      A2 a2 = DominatingValue<A2>::restore(CGF, a2_saved); -      A3 a3 = DominatingValue<A3>::restore(CGF, a3_saved); -      T(a0, a1, a2, a3).Emit(CGF, flags); -    } -     -  public: -    ConditionalCleanup4(A0_saved a0, A1_saved a1, A2_saved a2, A3_saved a3) -      : a0_saved(a0), a1_saved(a1), a2_saved(a2), a3_saved(a3) {} -  }; - -private: -  // The implementation for this class is in CGException.h and -  // CGException.cpp; the definition is here because it's used as a -  // member of CodeGenFunction. - -  /// The start of the scope-stack buffer, i.e. the allocated pointer -  /// for the buffer.  All of these pointers are either simultaneously -  /// null or simultaneously valid. -  char *StartOfBuffer; - -  /// The end of the buffer. -  char *EndOfBuffer; - -  /// The first valid entry in the buffer. -  char *StartOfData; - -  /// The innermost normal cleanup on the stack. -  stable_iterator InnermostNormalCleanup; - -  /// The innermost EH scope on the stack. -  stable_iterator InnermostEHScope; - -  /// The current set of branch fixups.  A branch fixup is a jump to -  /// an as-yet unemitted label, i.e. a label for which we don't yet -  /// know the EH stack depth.  Whenever we pop a cleanup, we have -  /// to thread all the current branch fixups through it. -  /// -  /// Fixups are recorded as the Use of the respective branch or -  /// switch statement.  The use points to the final destination. -  /// When popping out of a cleanup, these uses are threaded through -  /// the cleanup and adjusted to point to the new cleanup. -  /// -  /// Note that branches are allowed to jump into protected scopes -  /// in certain situations;  e.g. the following code is legal: -  ///     struct A { ~A(); }; // trivial ctor, non-trivial dtor -  ///     goto foo; -  ///     A a; -  ///    foo: -  ///     bar(); -  SmallVector<BranchFixup, 8> BranchFixups; - -  char *allocate(size_t Size); - -  void *pushCleanup(CleanupKind K, size_t DataSize); - -public: -  EHScopeStack() : StartOfBuffer(0), EndOfBuffer(0), StartOfData(0), -                   InnermostNormalCleanup(stable_end()), -                   InnermostEHScope(stable_end()) {} -  ~EHScopeStack() { delete[] StartOfBuffer; } - -  // Variadic templates would make this not terrible. - -  /// Push a lazily-created cleanup on the stack. -  template <class T> -  void pushCleanup(CleanupKind Kind) { -    void *Buffer = pushCleanup(Kind, sizeof(T)); -    Cleanup *Obj = new(Buffer) T(); -    (void) Obj; -  } - -  /// Push a lazily-created cleanup on the stack. -  template <class T, class A0> -  void pushCleanup(CleanupKind Kind, A0 a0) { -    void *Buffer = pushCleanup(Kind, sizeof(T)); -    Cleanup *Obj = new(Buffer) T(a0); -    (void) Obj; -  } - -  /// Push a lazily-created cleanup on the stack. -  template <class T, class A0, class A1> -  void pushCleanup(CleanupKind Kind, A0 a0, A1 a1) { -    void *Buffer = pushCleanup(Kind, sizeof(T)); -    Cleanup *Obj = new(Buffer) T(a0, a1); -    (void) Obj; -  } - -  /// Push a lazily-created cleanup on the stack. -  template <class T, class A0, class A1, class A2> -  void pushCleanup(CleanupKind Kind, A0 a0, A1 a1, A2 a2) { -    void *Buffer = pushCleanup(Kind, sizeof(T)); -    Cleanup *Obj = new(Buffer) T(a0, a1, a2); -    (void) Obj; -  } - -  /// Push a lazily-created cleanup on the stack. -  template <class T, class A0, class A1, class A2, class A3> -  void pushCleanup(CleanupKind Kind, A0 a0, A1 a1, A2 a2, A3 a3) { -    void *Buffer = pushCleanup(Kind, sizeof(T)); -    Cleanup *Obj = new(Buffer) T(a0, a1, a2, a3); -    (void) Obj; -  } - -  /// Push a lazily-created cleanup on the stack. -  template <class T, class A0, class A1, class A2, class A3, class A4> -  void pushCleanup(CleanupKind Kind, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { -    void *Buffer = pushCleanup(Kind, sizeof(T)); -    Cleanup *Obj = new(Buffer) T(a0, a1, a2, a3, a4); -    (void) Obj; -  } - -  // Feel free to add more variants of the following: - -  /// Push a cleanup with non-constant storage requirements on the -  /// stack.  The cleanup type must provide an additional static method: -  ///   static size_t getExtraSize(size_t); -  /// The argument to this method will be the value N, which will also -  /// be passed as the first argument to the constructor. -  /// -  /// The data stored in the extra storage must obey the same -  /// restrictions as normal cleanup member data. -  /// -  /// The pointer returned from this method is valid until the cleanup -  /// stack is modified. -  template <class T, class A0, class A1, class A2> -  T *pushCleanupWithExtra(CleanupKind Kind, size_t N, A0 a0, A1 a1, A2 a2) { -    void *Buffer = pushCleanup(Kind, sizeof(T) + T::getExtraSize(N)); -    return new (Buffer) T(N, a0, a1, a2); -  } - -  /// Pops a cleanup scope off the stack.  This is private to CGCleanup.cpp. -  void popCleanup(); - -  /// Push a set of catch handlers on the stack.  The catch is -  /// uninitialized and will need to have the given number of handlers -  /// set on it. -  class EHCatchScope *pushCatch(unsigned NumHandlers); - -  /// Pops a catch scope off the stack.  This is private to CGException.cpp. -  void popCatch(); - -  /// Push an exceptions filter on the stack. -  class EHFilterScope *pushFilter(unsigned NumFilters); - -  /// Pops an exceptions filter off the stack. -  void popFilter(); - -  /// Push a terminate handler on the stack. -  void pushTerminate(); - -  /// Pops a terminate handler off the stack. -  void popTerminate(); - -  /// Determines whether the exception-scopes stack is empty. -  bool empty() const { return StartOfData == EndOfBuffer; } - -  bool requiresLandingPad() const { -    return InnermostEHScope != stable_end(); -  } - -  /// Determines whether there are any normal cleanups on the stack. -  bool hasNormalCleanups() const { -    return InnermostNormalCleanup != stable_end(); -  } - -  /// Returns the innermost normal cleanup on the stack, or -  /// stable_end() if there are no normal cleanups. -  stable_iterator getInnermostNormalCleanup() const { -    return InnermostNormalCleanup; -  } -  stable_iterator getInnermostActiveNormalCleanup() const; - -  stable_iterator getInnermostEHScope() const { -    return InnermostEHScope; -  } - -  stable_iterator getInnermostActiveEHScope() const; - -  /// An unstable reference to a scope-stack depth.  Invalidated by -  /// pushes but not pops. -  class iterator; - -  /// Returns an iterator pointing to the innermost EH scope. -  iterator begin() const; - -  /// Returns an iterator pointing to the outermost EH scope. -  iterator end() const; - -  /// Create a stable reference to the top of the EH stack.  The -  /// returned reference is valid until that scope is popped off the -  /// stack. -  stable_iterator stable_begin() const { -    return stable_iterator(EndOfBuffer - StartOfData); -  } - -  /// Create a stable reference to the bottom of the EH stack. -  static stable_iterator stable_end() { -    return stable_iterator(0); -  } - -  /// Translates an iterator into a stable_iterator. -  stable_iterator stabilize(iterator it) const; - -  /// Turn a stable reference to a scope depth into a unstable pointer -  /// to the EH stack. -  iterator find(stable_iterator save) const; - -  /// Removes the cleanup pointed to by the given stable_iterator. -  void removeCleanup(stable_iterator save); - -  /// Add a branch fixup to the current cleanup scope. -  BranchFixup &addBranchFixup() { -    assert(hasNormalCleanups() && "adding fixup in scope without cleanups"); -    BranchFixups.push_back(BranchFixup()); -    return BranchFixups.back(); -  } - -  unsigned getNumBranchFixups() const { return BranchFixups.size(); } -  BranchFixup &getBranchFixup(unsigned I) { -    assert(I < getNumBranchFixups()); -    return BranchFixups[I]; -  } - -  /// Pops lazily-removed fixups from the end of the list.  This -  /// should only be called by procedures which have just popped a -  /// cleanup or resolved one or more fixups. -  void popNullFixups(); - -  /// Clears the branch-fixups list.  This should only be called by -  /// ResolveAllBranchFixups. -  void clearFixups() { BranchFixups.clear(); } -}; -  /// CodeGenFunction - This class organizes the per-function state that is used  /// while generating LLVM code.  class CodeGenFunction : public CodeGenTypeCache { @@ -606,6 +157,65 @@ public:    /// we prefer to insert allocas.    llvm::AssertingVH<llvm::Instruction> AllocaInsertPt; +  /// \brief API for captured statement code generation. +  class CGCapturedStmtInfo { +  public: +    explicit CGCapturedStmtInfo(const CapturedStmt &S, +                                CapturedRegionKind K = CR_Default) +      : Kind(K), ThisValue(0), CXXThisFieldDecl(0) { + +      RecordDecl::field_iterator Field = +        S.getCapturedRecordDecl()->field_begin(); +      for (CapturedStmt::const_capture_iterator I = S.capture_begin(), +                                                E = S.capture_end(); +           I != E; ++I, ++Field) { +        if (I->capturesThis()) +          CXXThisFieldDecl = *Field; +        else +          CaptureFields[I->getCapturedVar()] = *Field; +      } +    } + +    virtual ~CGCapturedStmtInfo(); + +    CapturedRegionKind getKind() const { return Kind; } + +    void setContextValue(llvm::Value *V) { ThisValue = V; } +    // \brief Retrieve the value of the context parameter. +    llvm::Value *getContextValue() const { return ThisValue; } + +    /// \brief Lookup the captured field decl for a variable. +    const FieldDecl *lookup(const VarDecl *VD) const { +      return CaptureFields.lookup(VD); +    } + +    bool isCXXThisExprCaptured() const { return CXXThisFieldDecl != 0; } +    FieldDecl *getThisFieldDecl() const { return CXXThisFieldDecl; } + +    /// \brief Emit the captured statement body. +    virtual void EmitBody(CodeGenFunction &CGF, Stmt *S) { +      CGF.EmitStmt(S); +    } + +    /// \brief Get the name of the capture helper. +    virtual StringRef getHelperName() const { return "__captured_stmt"; } + +  private: +    /// \brief The kind of captured statement being generated. +    CapturedRegionKind Kind; + +    /// \brief Keep the map between VarDecl and FieldDecl. +    llvm::SmallDenseMap<const VarDecl *, FieldDecl *> CaptureFields; + +    /// \brief The base address of the captured record, passed in as the first +    /// argument of the parallel region function. +    llvm::Value *ThisValue; + +    /// \brief Captured 'this' type. +    FieldDecl *CXXThisFieldDecl; +  }; +  CGCapturedStmtInfo *CapturedStmtInfo; +    /// BoundsChecking - Emit run-time bounds checks. Higher values mean    /// potentially higher performance penalties.    unsigned char BoundsChecking; @@ -631,6 +241,18 @@ public:    llvm::DenseMap<const VarDecl *, llvm::Value *> NRVOFlags;    EHScopeStack EHStack; +  llvm::SmallVector<char, 256> LifetimeExtendedCleanupStack; + +  /// Header for data within LifetimeExtendedCleanupStack. +  struct LifetimeExtendedCleanupHeader { +    /// The size of the following cleanup object. +    size_t Size : 29; +    /// The kind of cleanup to push: a value from the CleanupKind enumeration. +    unsigned Kind : 3; + +    size_t getSize() const { return Size; } +    CleanupKind getKind() const { return static_cast<CleanupKind>(Kind); } +  };    /// i32s containing the indexes of the cleanup destinations.    llvm::AllocaInst *NormalCleanupDest; @@ -766,6 +388,23 @@ public:      initFullExprCleanup();    } +  /// \brief Queue a cleanup to be pushed after finishing the current +  /// full-expression. +  template <class T, class A0, class A1, class A2, class A3> +  void pushCleanupAfterFullExpr(CleanupKind Kind, A0 a0, A1 a1, A2 a2, A3 a3) { +    assert(!isInConditionalBranch() && "can't defer conditional cleanup"); + +    LifetimeExtendedCleanupHeader Header = { sizeof(T), Kind }; + +    size_t OldSize = LifetimeExtendedCleanupStack.size(); +    LifetimeExtendedCleanupStack.resize( +        LifetimeExtendedCleanupStack.size() + sizeof(Header) + Header.Size); + +    char *Buffer = &LifetimeExtendedCleanupStack[OldSize]; +    new (Buffer) LifetimeExtendedCleanupHeader(Header); +    new (Buffer + sizeof(Header)) T(a0, a1, a2, a3); +  } +    /// Set up the last cleaup that was pushed as a conditional    /// full-expression cleanup.    void initFullExprCleanup(); @@ -784,9 +423,7 @@ public:    /// PopCleanupBlock - Will pop the cleanup entry on the stack and    /// process all branch fixups. -  /// \param EHLoc - Optional debug location for EH code. -  void PopCleanupBlock(bool FallThroughIsBranchThrough = false, -                       SourceLocation EHLoc=SourceLocation()); +  void PopCleanupBlock(bool FallThroughIsBranchThrough = false);    /// DeactivateCleanupBlock - Deactivates the given cleanup block.    /// The block cannot be reactivated.  Pops it if it's the top of the @@ -813,6 +450,7 @@ public:    /// will be executed once the scope is exited.    class RunCleanupsScope {      EHScopeStack::stable_iterator CleanupStackDepth; +    size_t LifetimeExtendedCleanupStackSize;      bool OldDidCallStackSave;    protected:      bool PerformCleanup; @@ -830,6 +468,8 @@ public:        : PerformCleanup(true), CGF(CGF)      {        CleanupStackDepth = CGF.EHStack.stable_begin(); +      LifetimeExtendedCleanupStackSize = +          CGF.LifetimeExtendedCleanupStack.size();        OldDidCallStackSave = CGF.DidCallStackSave;        CGF.DidCallStackSave = false;      } @@ -839,7 +479,8 @@ public:      ~RunCleanupsScope() {        if (PerformCleanup) {          CGF.DidCallStackSave = OldDidCallStackSave; -        CGF.PopCleanupBlocks(CleanupStackDepth); +        CGF.PopCleanupBlocks(CleanupStackDepth, +                             LifetimeExtendedCleanupStackSize);        }      } @@ -853,7 +494,8 @@ public:      void ForceCleanup() {        assert(PerformCleanup && "Already forced cleanup");        CGF.DidCallStackSave = OldDidCallStackSave; -      CGF.PopCleanupBlocks(CleanupStackDepth); +      CGF.PopCleanupBlocks(CleanupStackDepth, +                           LifetimeExtendedCleanupStackSize);        PerformCleanup = false;      }    }; @@ -905,11 +547,15 @@ public:    }; -  /// PopCleanupBlocks - Takes the old cleanup stack size and emits -  /// the cleanup blocks that have been added. -  /// \param EHLoc - Optional debug location for EH code. +  /// \brief Takes the old cleanup stack size and emits the cleanup blocks +  /// that have been added. +  void PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize); + +  /// \brief Takes the old cleanup stack size and emits the cleanup blocks +  /// that have been added, then adds all lifetime-extended cleanups from +  /// the given position to the stack.    void PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize, -                        SourceLocation EHLoc=SourceLocation()); +                        size_t OldLifetimeExtendedStackSize);    void ResolveBranchFixups(llvm::BasicBlock *Target); @@ -1152,10 +798,6 @@ private:    CGDebugInfo *DebugInfo;    bool DisableDebugInfo; -  /// If the current function returns 'this', use the field to keep track of -  /// the callee that returns 'this'. -  llvm::Value *CalleeWithThisReturn; -    /// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid    /// calling llvm.stacksave for multiple VLAs in the same scope.    bool DidCallStackSave; @@ -1279,6 +921,10 @@ private:    /// The current lexical scope.    LexicalScope *CurLexicalScope; +  /// The current source location that should be used for exception +  /// handling code. +  SourceLocation CurEHLocation; +    /// ByrefValueInfoMap - For each __block variable, contains a pair of the LLVM    /// type as well as the field number that contains the actual data.    llvm::DenseMap<const ValueDecl *, std::pair<llvm::Type *, @@ -1307,14 +953,6 @@ public:    CodeGenTypes &getTypes() const { return CGM.getTypes(); }    ASTContext &getContext() const { return CGM.getContext(); } -  /// Returns true if DebugInfo is actually initialized. -  bool maybeInitializeDebugInfo() { -    if (CGM.getModuleDebugInfo()) { -      DebugInfo = CGM.getModuleDebugInfo(); -      return true; -    } -    return false; -  }    CGDebugInfo *getDebugInfo() {       if (DisableDebugInfo)         return NULL; @@ -1378,12 +1016,15 @@ public:                       llvm::Value *addr, QualType type);    void pushDestroy(CleanupKind kind, llvm::Value *addr, QualType type,                     Destroyer *destroyer, bool useEHCleanupForArray); +  void pushLifetimeExtendedDestroy(CleanupKind kind, llvm::Value *addr, +                                   QualType type, Destroyer *destroyer, +                                   bool useEHCleanupForArray);    void emitDestroy(llvm::Value *addr, QualType type, Destroyer *destroyer,                     bool useEHCleanupForArray); -  llvm::Function *generateDestroyHelper(llvm::Constant *addr, -                                        QualType type, +  llvm::Function *generateDestroyHelper(llvm::Constant *addr, QualType type,                                          Destroyer *destroyer, -                                        bool useEHCleanupForArray); +                                        bool useEHCleanupForArray, +                                        const VarDecl *VD);    void emitArrayDestroy(llvm::Value *begin, llvm::Value *end,                          QualType type, Destroyer *destroyer,                          bool checkZeroLength, bool useEHCleanup); @@ -1495,9 +1136,9 @@ public:    void EmitConstructorBody(FunctionArgList &Args);    void EmitDestructorBody(FunctionArgList &Args);    void emitImplicitAssignmentOperatorBody(FunctionArgList &Args); -  void EmitFunctionBody(FunctionArgList &Args); +  void EmitFunctionBody(FunctionArgList &Args, const Stmt *Body); -  void EmitForwardingCallToLambda(const CXXRecordDecl *Lambda, +  void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator,                                    CallArgList &CallArgs);    void EmitLambdaToBlockPointerBody(FunctionArgList &Args);    void EmitLambdaBlockInvokeBody(); @@ -1512,6 +1153,11 @@ public:    /// legal to call this function even if there is no current insertion point.    void FinishFunction(SourceLocation EndLoc=SourceLocation()); +  void StartThunk(llvm::Function *Fn, GlobalDecl GD, const CGFunctionInfo &FnInfo); + +  void EmitCallAndReturnForThunk(GlobalDecl GD, llvm::Value *Callee, +                                 const ThunkInfo *Thunk); +    /// GenerateThunk - Generate a thunk for the given method.    void GenerateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo,                       GlobalDecl GD, const ThunkInfo &Thunk); @@ -1531,7 +1177,6 @@ public:    void InitializeVTablePointer(BaseSubobject Base,                                 const CXXRecordDecl *NearestVBase,                                 CharUnits OffsetFromNearestVBase, -                               llvm::Constant *VTable,                                 const CXXRecordDecl *VTableClass);    typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; @@ -1539,7 +1184,6 @@ public:                                  const CXXRecordDecl *NearestVBase,                                  CharUnits OffsetFromNearestVBase,                                  bool BaseIsNonVirtualPrimaryBase, -                                llvm::Constant *VTable,                                  const CXXRecordDecl *VTableClass,                                  VisitedVirtualBasesSetTy& VBases); @@ -1549,6 +1193,12 @@ public:    /// to by This.    llvm::Value *GetVTablePtr(llvm::Value *This, llvm::Type *Ty); + +  /// CanDevirtualizeMemberFunctionCalls - Checks whether virtual calls on given +  /// expr can be devirtualized. +  bool CanDevirtualizeMemberFunctionCall(const Expr *Base, +                                         const CXXMethodDecl *MD); +    /// EnterDtorCleanups - Enter the cleanups necessary to complete the    /// given phase of destruction for a destructor.  The end result    /// should call destructors on members and base classes in reverse @@ -1576,7 +1226,8 @@ public:    /// EmitFunctionEpilog - Emit the target specific LLVM code to return the    /// given temporary. -  void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc); +  void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc, +                          SourceLocation EndLoc);    /// EmitStartEHSpec - Emit the start of the exception spec.    void EmitStartEHSpec(const Decl *D); @@ -1678,8 +1329,7 @@ public:    /// ErrorUnsupported - Print out an error that codegen doesn't support the    /// specified stmt yet. -  void ErrorUnsupported(const Stmt *S, const char *Type, -                        bool OmitOnError=false); +  void ErrorUnsupported(const Stmt *S, const char *Type);    //===--------------------------------------------------------------------===//    //                                  Helpers @@ -1915,10 +1565,6 @@ public:                                          CastExpr::path_const_iterator PathEnd,                                          bool NullCheckValue); -  llvm::Value *GetVirtualBaseClassOffset(llvm::Value *This, -                                         const CXXRecordDecl *ClassDecl, -                                         const CXXRecordDecl *BaseClassDecl); -    /// GetVTTParameter - Return the VTT parameter that should be passed to a    /// base constructor/destructor with virtual bases.    /// FIXME: VTTs are Itanium ABI-specific, so the definition should move @@ -1928,7 +1574,8 @@ public:    void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,                                        CXXCtorType CtorType, -                                      const FunctionArgList &Args); +                                      const FunctionArgList &Args, +                                      SourceLocation Loc);    // It's important not to confuse this and the previous function. Delegating    // constructors are the C++0x feature. The constructor delegate optimization    // is used to reduce duplication in the base and complete consturctors where @@ -1982,10 +1629,6 @@ public:    llvm::Value *EmitDynamicCast(llvm::Value *V, const CXXDynamicCastExpr *DCE);    llvm::Value* EmitCXXUuidofExpr(const CXXUuidofExpr *E); -  void MaybeEmitStdInitializerListCleanup(llvm::Value *loc, const Expr *init); -  void EmitStdInitializerListCleanup(llvm::Value *loc, -                                     const InitListExpr *init); -    /// \brief Situations in which we might emit a check for the suitability of a    ///        pointer or glvalue.    enum TypeCheckKind { @@ -2161,11 +1804,12 @@ public:    /// \return True if the statement was handled.    bool EmitSimpleStmt(const Stmt *S); -  RValue EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false, -                          AggValueSlot AVS = AggValueSlot::ignored()); -  RValue EmitCompoundStmtWithoutScope(const CompoundStmt &S, -                                      bool GetLast = false, AggValueSlot AVS = -                                          AggValueSlot::ignored()); +  llvm::Value *EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false, +                                AggValueSlot AVS = AggValueSlot::ignored()); +  llvm::Value *EmitCompoundStmtWithoutScope(const CompoundStmt &S, +                                            bool GetLast = false, +                                            AggValueSlot AVS = +                                                AggValueSlot::ignored());    /// EmitLabel - Emit the block for the given label. It is legal to call this    /// function even if there is no current insertion point. @@ -2188,7 +1832,6 @@ public:    void EmitCaseStmt(const CaseStmt &S);    void EmitCaseStmtRange(const CaseStmt &S);    void EmitAsmStmt(const AsmStmt &S); -  void EmitCapturedStmt(const CapturedStmt &S);    void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S);    void EmitObjCAtTryStmt(const ObjCAtTryStmt &S); @@ -2202,8 +1845,14 @@ public:    void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);    void EmitCXXTryStmt(const CXXTryStmt &S); +  void EmitSEHTryStmt(const SEHTryStmt &S);    void EmitCXXForRangeStmt(const CXXForRangeStmt &S); +  llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K); +  llvm::Function *GenerateCapturedStmtFunction(const CapturedDecl *CD, +                                               const RecordDecl *RD, +                                               SourceLocation Loc); +    //===--------------------------------------------------------------------===//    //                         LValue Expression Emission    //===--------------------------------------------------------------------===// @@ -2245,11 +1894,12 @@ public:    /// that the address will be used to access the object.    LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK); -  RValue convertTempToRValue(llvm::Value *addr, QualType type); +  RValue convertTempToRValue(llvm::Value *addr, QualType type, +                             SourceLocation Loc);    void EmitAtomicInit(Expr *E, LValue lvalue); -  RValue EmitAtomicLoad(LValue lvalue, +  RValue EmitAtomicLoad(LValue lvalue, SourceLocation loc,                          AggValueSlot slot = AggValueSlot::ignored());    void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit); @@ -2267,6 +1917,7 @@ public:    /// the LLVM value representation.    llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,                                  unsigned Alignment, QualType Ty, +                                SourceLocation Loc,                                  llvm::MDNode *TBAAInfo = 0,                                  QualType TBAABaseTy = QualType(),                                  uint64_t TBAAOffset = 0); @@ -2275,7 +1926,7 @@ public:    /// care to appropriately convert from the memory representation to    /// the LLVM value representation.  The l-value must be a simple    /// l-value. -  llvm::Value *EmitLoadOfScalar(LValue lvalue); +  llvm::Value *EmitLoadOfScalar(LValue lvalue, SourceLocation Loc);    /// EmitStoreOfScalar - Store a scalar value to an address, taking    /// care to appropriately convert from the memory representation to @@ -2296,7 +1947,7 @@ public:    /// EmitLoadOfLValue - Given an expression that represents a value lvalue,    /// this method emits the address of the lvalue, then loads the result as an    /// rvalue, returning the rvalue. -  RValue EmitLoadOfLValue(LValue V); +  RValue EmitLoadOfLValue(LValue V, SourceLocation Loc);    RValue EmitLoadOfExtVectorElementLValue(LValue V);    RValue EmitLoadOfBitfieldLValue(LValue LV); @@ -2306,8 +1957,8 @@ public:    void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false);    void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst); -  /// EmitStoreThroughLValue - Store Src into Dst with same constraints as -  /// EmitStoreThroughLValue. +  /// EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints +  /// as EmitStoreThroughLValue.    ///    /// \param Result [out] - If non-null, this will be set to a Value* for the    /// bit-field contents after the store, appropriate for use as the result of @@ -2318,6 +1969,8 @@ public:    /// Emit an l-value for an assignment (simple or compound) of complex type.    LValue EmitComplexAssignmentLValue(const BinaryOperator *E);    LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E); +  LValue EmitScalarCompooundAssignWithComplex(const CompoundAssignOperator *E, +                                              llvm::Value *&Result);    // Note: only available for agg return types    LValue EmitBinaryOperatorLValue(const BinaryOperator *E); @@ -2340,11 +1993,10 @@ public:    LValue EmitInitListLValue(const InitListExpr *E);    LValue EmitConditionalOperatorLValue(const AbstractConditionalOperator *E);    LValue EmitCastLValue(const CastExpr *E); -  LValue EmitNullInitializationLValue(const CXXScalarValueInitExpr *E);    LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);    LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e); -  RValue EmitRValueForField(LValue LV, const FieldDecl *FD); +  RValue EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc);    class ConstantEmission {      llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference; @@ -2359,7 +2011,7 @@ public:        return ConstantEmission(C, false);      } -    operator bool() const { return ValueAndIsReference.getOpaqueValue() != 0; } +    LLVM_EXPLICIT operator bool() const { return ValueAndIsReference.getOpaqueValue() != 0; }      bool isReference() const { return ValueAndIsReference.getInt(); }      LValue getReferenceLValue(CodeGenFunction &CGF, Expr *refExpr) const { @@ -2426,6 +2078,7 @@ public:                    llvm::Instruction **callOrInvoke = 0);    RValue EmitCall(QualType FnType, llvm::Value *Callee, +                  SourceLocation CallLoc,                    ReturnValueSlot ReturnValue,                    CallExpr::const_arg_iterator ArgBeg,                    CallExpr::const_arg_iterator ArgEnd, @@ -2457,10 +2110,6 @@ public:    void EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee,                                         ArrayRef<llvm::Value*> args); -  llvm::Value *BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This, -                                llvm::Type *Ty); -  llvm::Value *BuildVirtualCall(const CXXDestructorDecl *DD, CXXDtorType Type, -                                llvm::Value *This, llvm::Type *Ty);    llvm::Value *BuildAppleKextVirtualCall(const CXXMethodDecl *MD,                                            NestedNameSpecifier *Qual,                                           llvm::Type *Ty); @@ -2503,6 +2152,11 @@ public:    /// is unhandled by the current target.    llvm::Value *EmitTargetBuiltinExpr(unsigned BuiltinID, const CallExpr *E); +  llvm::Value *EmitAArch64CompareBuiltinExpr(llvm::Value *Op, llvm::Type *Ty, +                                             const llvm::CmpInst::Predicate Fp, +                                             const llvm::CmpInst::Predicate Ip, +                                             const llvm::Twine &Name = ""); +  llvm::Value *EmitAArch64CompareBuiltinExpr(llvm::Value *Op, llvm::Type *Ty);    llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E);    llvm::Value *EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E);    llvm::Value *EmitNeonCall(llvm::Function *F, @@ -2512,6 +2166,8 @@ public:    llvm::Value *EmitNeonSplat(llvm::Value *V, llvm::Constant *Idx);    llvm::Value *EmitNeonShiftVector(llvm::Value *V, llvm::Type *Ty,                                     bool negateForRightShift); +  llvm::Value *EmitNeonRShiftImm(llvm::Value *Vec, llvm::Value *Amt, +                                 llvm::Type *Ty, bool usgn, const char *name);    llvm::Value *BuildVector(ArrayRef<llvm::Value*> Ops);    llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E); @@ -2587,10 +2243,8 @@ public:    void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr);    void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr);  -  /// EmitReferenceBindingToExpr - Emits a reference binding to the passed in -  /// expression. Will emit a temporary variable if E is not an LValue. -  RValue EmitReferenceBindingToExpr(const Expr* E, -                                    const NamedDecl *InitializedDecl); +  /// \brief Emits a reference binding to the passed in expression. +  RValue EmitReferenceBindingToExpr(const Expr *E);    //===--------------------------------------------------------------------===//    //                           Expression Emission @@ -2646,7 +2300,7 @@ public:    void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit);    /// EmitLoadOfComplex - Load a complex number from the specified l-value. -  ComplexPairTy EmitLoadOfComplex(LValue src); +  ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc);    /// CreateStaticVarDecl - Create a zero-initialized LLVM global for    /// a static local variable. @@ -2670,7 +2324,8 @@ public:    /// Call atexit() with a function that passes the given argument to    /// the given function. -  void registerGlobalDtorWithAtExit(llvm::Constant *fn, llvm::Constant *addr); +  void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::Constant *fn, +                                    llvm::Constant *addr);    /// Emit code in this function to perform a guarded variable    /// initialization.  Guarded initializations are used when it's not @@ -2801,7 +2456,8 @@ public:    /// EmitDelegateCallArg - We are performing a delegate call; that    /// is, the current function is delegating to another one.  Produce    /// a r-value suitable for passing the given parameter. -  void EmitDelegateCallArg(CallArgList &args, const VarDecl *param); +  void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, +                           SourceLocation loc);    /// SetFPAccuracy - Set the minimum required accuracy of the given floating    /// point operation, expressed as the maximum relative error in ulp. @@ -2825,7 +2481,7 @@ private:    /// Ty, into individual arguments on the provided vector \arg Args. See    /// ABIArgInfo::Expand.    void ExpandTypeToArgs(QualType Ty, RValue Src, -                        SmallVector<llvm::Value*, 16> &Args, +                        SmallVectorImpl<llvm::Value *> &Args,                          llvm::FunctionType *IRFuncTy);    llvm::Value* EmitAsmInput(const TargetInfo::ConstraintInfo &Info, @@ -2833,7 +2489,8 @@ private:    llvm::Value* EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info,                                    LValue InputValue, QualType InputType, -                                  std::string &ConstraintStr); +                                  std::string &ConstraintStr, +                                  SourceLocation Loc);    /// EmitCallArgs - Emit call arguments for a function.    /// The CallArgTypeInfo parameter is used for iterating over the known @@ -2841,8 +2498,13 @@ private:    template<typename T>    void EmitCallArgs(CallArgList& Args, const T* CallArgTypeInfo,                      CallExpr::const_arg_iterator ArgBeg, -                    CallExpr::const_arg_iterator ArgEnd) { -      CallExpr::const_arg_iterator Arg = ArgBeg; +                    CallExpr::const_arg_iterator ArgEnd, +                    bool ForceColumnInfo = false) { +    CGDebugInfo *DI = getDebugInfo(); +    SourceLocation CallLoc; +    if (DI) CallLoc = DI->getLocation(); + +    CallExpr::const_arg_iterator Arg = ArgBeg;      // First, use the argument types that the type info knows about      if (CallArgTypeInfo) { @@ -2871,6 +2533,10 @@ private:                 "type mismatch in call argument!");  #endif          EmitCallArg(Args, *Arg, ArgType); + +        // Each argument expression could modify the debug +        // location. Restore it. +        if (DI) DI->EmitLocation(Builder, CallLoc, ForceColumnInfo);        }        // Either we've emitted all the call args, or we have a call to a @@ -2881,8 +2547,12 @@ private:      }      // If we still have any arguments, emit them using the type of the argument. -    for (; Arg != ArgEnd; ++Arg) +    for (; Arg != ArgEnd; ++Arg) {        EmitCallArg(Args, *Arg, Arg->getType()); + +      // Restore the debug location. +      if (DI) DI->EmitLocation(Builder, CallLoc, ForceColumnInfo); +    }    }    const TargetCodeGenInfo &getTargetHooks() const { diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 0b03a3c4b67db..792fbfce33497 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -35,7 +35,9 @@  #include "clang/Basic/Module.h"  #include "clang/Basic/SourceManager.h"  #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/Version.h"  #include "clang/Frontend/CodeGenOptions.h" +#include "clang/Sema/SemaDiagnostic.h"  #include "llvm/ADT/APSInt.h"  #include "llvm/ADT/Triple.h"  #include "llvm/IR/CallingConv.h" @@ -67,25 +69,23 @@ static CGCXXABI &createCXXABI(CodeGenModule &CGM) {    llvm_unreachable("invalid C++ ABI kind");  } -  CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,                               llvm::Module &M, const llvm::DataLayout &TD,                               DiagnosticsEngine &diags) -  : Context(C), LangOpts(C.getLangOpts()), CodeGenOpts(CGO), TheModule(M), -    Diags(diags), TheDataLayout(TD), Target(C.getTargetInfo()), -    ABI(createCXXABI(*this)), VMContext(M.getContext()), TBAA(0), -    TheTargetCodeGenInfo(0), Types(*this), VTables(*this), -    ObjCRuntime(0), OpenCLRuntime(0), CUDARuntime(0), -    DebugInfo(0), ARCData(0), NoObjCARCExceptionsMetadata(0), -    RRData(0), CFConstantStringClassRef(0), -    ConstantStringClassRef(0), NSConstantStringType(0), -    NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), -    BlockObjectAssign(0), BlockObjectDispose(0), -    BlockDescriptorType(0), GenericBlockLiteralType(0), -    LifetimeStartFn(0), LifetimeEndFn(0), -    SanitizerBlacklist(CGO.SanitizerBlacklistFile), -    SanOpts(SanitizerBlacklist.isIn(M) ? -            SanitizerOptions::Disabled : LangOpts.Sanitize) { +    : Context(C), LangOpts(C.getLangOpts()), CodeGenOpts(CGO), TheModule(M), +      Diags(diags), TheDataLayout(TD), Target(C.getTargetInfo()), +      ABI(createCXXABI(*this)), VMContext(M.getContext()), TBAA(0), +      TheTargetCodeGenInfo(0), Types(*this), VTables(*this), ObjCRuntime(0), +      OpenCLRuntime(0), CUDARuntime(0), DebugInfo(0), ARCData(0), +      NoObjCARCExceptionsMetadata(0), RRData(0), CFConstantStringClassRef(0), +      ConstantStringClassRef(0), NSConstantStringType(0), +      NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockObjectAssign(0), +      BlockObjectDispose(0), BlockDescriptorType(0), GenericBlockLiteralType(0), +      LifetimeStartFn(0), LifetimeEndFn(0), +      SanitizerBlacklist( +          llvm::SpecialCaseList::createOrDie(CGO.SanitizerBlacklistFile)), +      SanOpts(SanitizerBlacklist->isIn(M) ? SanitizerOptions::Disabled +                                          : LangOpts.Sanitize) {    // Initialize the type cache.    llvm::LLVMContext &LLVMContext = M.getContext(); @@ -172,8 +172,71 @@ void CodeGenModule::createCUDARuntime() {    CUDARuntime = CreateNVCUDARuntime(*this);  } +void CodeGenModule::applyReplacements() { +  for (ReplacementsTy::iterator I = Replacements.begin(), +                                E = Replacements.end(); +       I != E; ++I) { +    StringRef MangledName = I->first(); +    llvm::Constant *Replacement = I->second; +    llvm::GlobalValue *Entry = GetGlobalValue(MangledName); +    if (!Entry) +      continue; +    llvm::Function *OldF = cast<llvm::Function>(Entry); +    llvm::Function *NewF = dyn_cast<llvm::Function>(Replacement); +    if (!NewF) { +      llvm::ConstantExpr *CE = cast<llvm::ConstantExpr>(Replacement); +      assert(CE->getOpcode() == llvm::Instruction::BitCast || +             CE->getOpcode() == llvm::Instruction::GetElementPtr); +      NewF = dyn_cast<llvm::Function>(CE->getOperand(0)); +    } + +    // Replace old with new, but keep the old order. +    OldF->replaceAllUsesWith(Replacement); +    if (NewF) { +      NewF->removeFromParent(); +      OldF->getParent()->getFunctionList().insertAfter(OldF, NewF); +    } +    OldF->eraseFromParent(); +  } +} + +void CodeGenModule::checkAliases() { +  bool Error = false; +  for (std::vector<GlobalDecl>::iterator I = Aliases.begin(), +         E = Aliases.end(); I != E; ++I) { +    const GlobalDecl &GD = *I; +    const ValueDecl *D = cast<ValueDecl>(GD.getDecl()); +    const AliasAttr *AA = D->getAttr<AliasAttr>(); +    StringRef MangledName = getMangledName(GD); +    llvm::GlobalValue *Entry = GetGlobalValue(MangledName); +    llvm::GlobalAlias *Alias = cast<llvm::GlobalAlias>(Entry); +    llvm::GlobalValue *GV = Alias->getAliasedGlobal(); +    if (GV->isDeclaration()) { +      Error = true; +      getDiags().Report(AA->getLocation(), diag::err_alias_to_undefined); +    } else if (!Alias->resolveAliasedGlobal(/*stopOnWeak*/ false)) { +      Error = true; +      getDiags().Report(AA->getLocation(), diag::err_cyclic_alias); +    } +  } +  if (!Error) +    return; + +  for (std::vector<GlobalDecl>::iterator I = Aliases.begin(), +         E = Aliases.end(); I != E; ++I) { +    const GlobalDecl &GD = *I; +    StringRef MangledName = getMangledName(GD); +    llvm::GlobalValue *Entry = GetGlobalValue(MangledName); +    llvm::GlobalAlias *Alias = cast<llvm::GlobalAlias>(Entry); +    Alias->replaceAllUsesWith(llvm::UndefValue::get(Alias->getType())); +    Alias->eraseFromParent(); +  } +} +  void CodeGenModule::Release() {    EmitDeferred(); +  applyReplacements(); +  checkAliases();    EmitCXXGlobalInitFunc();    EmitCXXGlobalDtorFunc();    EmitCXXThreadLocalInitFunc(); @@ -186,9 +249,23 @@ void CodeGenModule::Release() {    EmitStaticExternCAliases();    EmitLLVMUsed(); -  if (CodeGenOpts.Autolink && Context.getLangOpts().Modules) { +  if (CodeGenOpts.Autolink && +      (Context.getLangOpts().Modules || !LinkerOptionsMetadata.empty())) {      EmitModuleLinkOptions();    } +  if (CodeGenOpts.DwarfVersion) +    // We actually want the latest version when there are conflicts. +    // We can change from Warning to Latest if such mode is supported. +    getModule().addModuleFlag(llvm::Module::Warning, "Dwarf Version", +                              CodeGenOpts.DwarfVersion); +  if (DebugInfo) +    // We support a single version in the linked module: error out when +    // modules do not have the same version. We are going to implement dropping +    // debug info when the version number is not up-to-date. Once that is +    // done, the bitcode linker is not going to see modules with different +    // version numbers. +    getModule().addModuleFlag(llvm::Module::Error, "Debug Info Version", +                              llvm::DEBUG_METADATA_VERSION);    SimplifyPersonality(); @@ -200,6 +277,8 @@ void CodeGenModule::Release() {    if (DebugInfo)      DebugInfo->finalize(); + +  EmitVersionIdentMetadata();  }  void CodeGenModule::UpdateCompletedType(const TagDecl *TD) { @@ -239,14 +318,14 @@ llvm::MDNode *CodeGenModule::getTBAAStructTagInfo(QualType BaseTy,    return TBAA->getTBAAStructTagInfo(BaseTy, AccessN, O);  } -/// Decorate the instruction with a TBAA tag. For scalar TBAA, the tag -/// is the same as the type. For struct-path aware TBAA, the tag -/// is different from the type: base type, access type and offset. +/// Decorate the instruction with a TBAA tag. For both scalar TBAA +/// and struct-path aware TBAA, the tag has the same format: +/// base type, access type and offset.  /// When ConvertTypeToTag is true, we create a tag based on the scalar type.  void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst,                                          llvm::MDNode *TBAAInfo,                                          bool ConvertTypeToTag) { -  if (ConvertTypeToTag && TBAA && CodeGenOpts.StructPathTBAA) +  if (ConvertTypeToTag && TBAA)      Inst->setMetadata(llvm::LLVMContext::MD_tbaa,                        TBAA->getTBAAScalarTagInfo(TBAAInfo));    else @@ -260,10 +339,7 @@ void CodeGenModule::Error(SourceLocation loc, StringRef error) {  /// ErrorUnsupported - Print out an error that codegen doesn't support the  /// specified stmt yet. -void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type, -                                     bool OmitOnError) { -  if (OmitOnError && getDiags().hasErrorOccurred()) -    return; +void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type) {    unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,                                                 "cannot compile this %0 yet");    std::string Msg = Type; @@ -273,10 +349,7 @@ void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type,  /// ErrorUnsupported - Print out an error that codegen doesn't support the  /// specified decl yet. -void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type, -                                     bool OmitOnError) { -  if (OmitOnError && getDiags().hasErrorOccurred()) -    return; +void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type) {    unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,                                                 "cannot compile this %0 yet");    std::string Msg = Type; @@ -428,9 +501,6 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) {      getCXXABI().getMangleContext().mangleCXXCtor(D, GD.getCtorType(), Out);    else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))      getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Out); -  else if (const BlockDecl *BD = dyn_cast<BlockDecl>(ND)) -    getCXXABI().getMangleContext().mangleBlock(BD, Out, -      dyn_cast_or_null<VarDecl>(initializedGlobalDecl.getDecl()));    else      getCXXABI().getMangleContext().mangleName(ND, Out); @@ -508,7 +578,14 @@ void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) {  }  llvm::GlobalValue::LinkageTypes -CodeGenModule::getFunctionLinkage(const FunctionDecl *D) { +CodeGenModule::getFunctionLinkage(GlobalDecl GD) { +  const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl()); + +  if (isa<CXXDestructorDecl>(D) && +      getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D), +                                         GD.getDtorType())) +    return llvm::Function::LinkOnceODRLinkage; +    GVALinkage Linkage = getContext().GetGVALinkageForFunction(D);    if (Linkage == GVA_Internal) @@ -597,61 +674,66 @@ static bool hasUnwindExceptions(const LangOptions &LangOpts) {  void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,                                                             llvm::Function *F) { +  llvm::AttrBuilder B; +    if (CodeGenOpts.UnwindTables) -    F->setHasUWTable(); +    B.addAttribute(llvm::Attribute::UWTable);    if (!hasUnwindExceptions(LangOpts)) -    F->addFnAttr(llvm::Attribute::NoUnwind); +    B.addAttribute(llvm::Attribute::NoUnwind);    if (D->hasAttr<NakedAttr>()) {      // Naked implies noinline: we should not be inlining such functions. -    F->addFnAttr(llvm::Attribute::Naked); -    F->addFnAttr(llvm::Attribute::NoInline); +    B.addAttribute(llvm::Attribute::Naked); +    B.addAttribute(llvm::Attribute::NoInline); +  } else if (D->hasAttr<NoInlineAttr>()) { +    B.addAttribute(llvm::Attribute::NoInline); +  } else if ((D->hasAttr<AlwaysInlineAttr>() || +              D->hasAttr<ForceInlineAttr>()) && +             !F->getAttributes().hasAttribute(llvm::AttributeSet::FunctionIndex, +                                              llvm::Attribute::NoInline)) { +    // (noinline wins over always_inline, and we can't specify both in IR) +    B.addAttribute(llvm::Attribute::AlwaysInline);    } -  if (D->hasAttr<NoInlineAttr>()) -    F->addFnAttr(llvm::Attribute::NoInline); - -  // (noinline wins over always_inline, and we can't specify both in IR) -  if ((D->hasAttr<AlwaysInlineAttr>() || D->hasAttr<ForceInlineAttr>()) && -      !F->getAttributes().hasAttribute(llvm::AttributeSet::FunctionIndex, -                                       llvm::Attribute::NoInline)) -    F->addFnAttr(llvm::Attribute::AlwaysInline); - -  // FIXME: Communicate hot and cold attributes to LLVM more directly. -  if (D->hasAttr<ColdAttr>()) -    F->addFnAttr(llvm::Attribute::OptimizeForSize); +  if (D->hasAttr<ColdAttr>()) { +    B.addAttribute(llvm::Attribute::OptimizeForSize); +    B.addAttribute(llvm::Attribute::Cold); +  }    if (D->hasAttr<MinSizeAttr>()) -    F->addFnAttr(llvm::Attribute::MinSize); - -  if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D)) -    F->setUnnamedAddr(true); - -  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) -    if (MD->isVirtual()) -      F->setUnnamedAddr(true); +    B.addAttribute(llvm::Attribute::MinSize);    if (LangOpts.getStackProtector() == LangOptions::SSPOn) -    F->addFnAttr(llvm::Attribute::StackProtect); +    B.addAttribute(llvm::Attribute::StackProtect);    else if (LangOpts.getStackProtector() == LangOptions::SSPReq) -    F->addFnAttr(llvm::Attribute::StackProtectReq); +    B.addAttribute(llvm::Attribute::StackProtectReq);    // Add sanitizer attributes if function is not blacklisted. -  if (!SanitizerBlacklist.isIn(*F)) { +  if (!SanitizerBlacklist->isIn(*F)) {      // When AddressSanitizer is enabled, set SanitizeAddress attribute      // unless __attribute__((no_sanitize_address)) is used.      if (SanOpts.Address && !D->hasAttr<NoSanitizeAddressAttr>()) -      F->addFnAttr(llvm::Attribute::SanitizeAddress); +      B.addAttribute(llvm::Attribute::SanitizeAddress);      // Same for ThreadSanitizer and __attribute__((no_sanitize_thread))      if (SanOpts.Thread && !D->hasAttr<NoSanitizeThreadAttr>()) { -      F->addFnAttr(llvm::Attribute::SanitizeThread); +      B.addAttribute(llvm::Attribute::SanitizeThread);      }      // Same for MemorySanitizer and __attribute__((no_sanitize_memory))      if (SanOpts.Memory && !D->hasAttr<NoSanitizeMemoryAttr>()) -      F->addFnAttr(llvm::Attribute::SanitizeMemory); +      B.addAttribute(llvm::Attribute::SanitizeMemory);    } +  F->addAttributes(llvm::AttributeSet::FunctionIndex, +                   llvm::AttributeSet::get( +                       F->getContext(), llvm::AttributeSet::FunctionIndex, B)); + +  if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D)) +    F->setUnnamedAddr(true); +  else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) +    if (MD->isVirtual()) +      F->setUnnamedAddr(true); +    unsigned alignment = D->getMaxAlignment() / Context.getCharWidth();    if (alignment)      F->setAlignment(alignment); @@ -706,6 +788,14 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD,    if (!IsIncompleteFunction)      SetLLVMFunctionAttributes(FD, getTypes().arrangeGlobalDeclaration(GD), F); +  if (getCXXABI().HasThisReturn(GD)) { +    assert(!F->arg_empty() && +           F->arg_begin()->getType() +             ->canLosslesslyBitCastTo(F->getReturnType()) && +           "unexpected this return"); +    F->addAttribute(1, llvm::Attribute::Returned); +  } +    // Only a few attributes are set on declarations; these may later be    // overridden by a definition. @@ -727,6 +817,12 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD,    if (const SectionAttr *SA = FD->getAttr<SectionAttr>())      F->setSection(SA->getName()); + +  // A replaceable global allocation function does not act like a builtin by +  // default, only if it is invoked by a new-expression or delete-expression. +  if (FD->isReplaceableGlobalAllocationFunction()) +    F->addAttribute(llvm::AttributeSet::FunctionIndex, +                    llvm::Attribute::NoBuiltin);  }  void CodeGenModule::AddUsedGlobal(llvm::GlobalValue *GV) { @@ -762,31 +858,48 @@ void CodeGenModule::EmitLLVMUsed() {    GV->setSection("llvm.metadata");  } +void CodeGenModule::AppendLinkerOptions(StringRef Opts) { +  llvm::Value *MDOpts = llvm::MDString::get(getLLVMContext(), Opts); +  LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts)); +} + +void CodeGenModule::AddDetectMismatch(StringRef Name, StringRef Value) { +  llvm::SmallString<32> Opt; +  getTargetCodeGenInfo().getDetectMismatchOption(Name, Value, Opt); +  llvm::Value *MDOpts = llvm::MDString::get(getLLVMContext(), Opt); +  LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts)); +} + +void CodeGenModule::AddDependentLib(StringRef Lib) { +  llvm::SmallString<24> Opt; +  getTargetCodeGenInfo().getDependentLibraryOption(Lib, Opt); +  llvm::Value *MDOpts = llvm::MDString::get(getLLVMContext(), Opt); +  LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts)); +} +  /// \brief Add link options implied by the given module, including modules  /// it depends on, using a postorder walk. -static void addLinkOptionsPostorder(llvm::LLVMContext &Context, +static void addLinkOptionsPostorder(CodeGenModule &CGM,                                      Module *Mod,                                      SmallVectorImpl<llvm::Value *> &Metadata,                                      llvm::SmallPtrSet<Module *, 16> &Visited) {    // Import this module's parent.    if (Mod->Parent && Visited.insert(Mod->Parent)) { -    addLinkOptionsPostorder(Context, Mod->Parent, Metadata, Visited); +    addLinkOptionsPostorder(CGM, Mod->Parent, Metadata, Visited);    }    // Import this module's dependencies.    for (unsigned I = Mod->Imports.size(); I > 0; --I) {      if (Visited.insert(Mod->Imports[I-1])) -      addLinkOptionsPostorder(Context, Mod->Imports[I-1], Metadata, Visited); +      addLinkOptionsPostorder(CGM, Mod->Imports[I-1], Metadata, Visited);    }    // Add linker options to link against the libraries/frameworks    // described by this module. +  llvm::LLVMContext &Context = CGM.getLLVMContext();    for (unsigned I = Mod->LinkLibraries.size(); I > 0; --I) { -    // FIXME: -lfoo is Unix-centric and -framework Foo is Darwin-centric. -    // We need to know more about the linker to know how to encode these -    // options propertly. - -    // Link against a framework. +    // Link against a framework.  Frameworks are currently Darwin only, so we +    // don't to ask TargetCodeGenInfo for the spelling of the linker option.      if (Mod->LinkLibraries[I-1].IsFramework) {        llvm::Value *Args[2] = {          llvm::MDString::get(Context, "-framework"), @@ -798,9 +911,10 @@ static void addLinkOptionsPostorder(llvm::LLVMContext &Context,      }      // Link against a library. -    llvm::Value *OptString -    = llvm::MDString::get(Context, -                          "-l" + Mod->LinkLibraries[I-1].Library); +    llvm::SmallString<24> Opt; +    CGM.getTargetCodeGenInfo().getDependentLibraryOption( +      Mod->LinkLibraries[I-1].Library, Opt); +    llvm::Value *OptString = llvm::MDString::get(Context, Opt);      Metadata.push_back(llvm::MDNode::get(Context, OptString));    }  } @@ -824,8 +938,7 @@ void CodeGenModule::EmitModuleLinkOptions() {    // Find all of the modules to import, making a little effort to prune    // non-leaf modules.    while (!Stack.empty()) { -    clang::Module *Mod = Stack.back(); -    Stack.pop_back(); +    clang::Module *Mod = Stack.pop_back_val();      bool AnyChildren = false; @@ -852,20 +965,23 @@ void CodeGenModule::EmitModuleLinkOptions() {    }    // Add link options for all of the imported modules in reverse topological -  // order. +  // order.  We don't do anything to try to order import link flags with respect +  // to linker options inserted by things like #pragma comment().    SmallVector<llvm::Value *, 16> MetadataArgs;    Visited.clear();    for (llvm::SetVector<clang::Module *>::iterator M = LinkModules.begin(),                                                 MEnd = LinkModules.end();         M != MEnd; ++M) {      if (Visited.insert(*M)) -      addLinkOptionsPostorder(getLLVMContext(), *M, MetadataArgs, Visited); +      addLinkOptionsPostorder(*this, *M, MetadataArgs, Visited);    }    std::reverse(MetadataArgs.begin(), MetadataArgs.end()); +  LinkerOptionsMetadata.append(MetadataArgs.begin(), MetadataArgs.end());    // Add the linker options metadata flag.    getModule().addModuleFlag(llvm::Module::AppendUnique, "Linker Options", -                            llvm::MDNode::get(getLLVMContext(), MetadataArgs)); +                            llvm::MDNode::get(getLLVMContext(), +                                              LinkerOptionsMetadata));  }  void CodeGenModule::EmitDeferred() { @@ -928,9 +1044,9 @@ void CodeGenModule::EmitGlobalAnnotations() {  }  llvm::Constant *CodeGenModule::EmitAnnotationString(StringRef Str) { -  llvm::StringMap<llvm::Constant*>::iterator i = AnnotationStrings.find(Str); -  if (i != AnnotationStrings.end()) -    return i->second; +  llvm::Constant *&AStr = AnnotationStrings[Str]; +  if (AStr) +    return AStr;    // Not found yet, create a new global.    llvm::Constant *s = llvm::ConstantDataArray::getString(getLLVMContext(), Str); @@ -938,7 +1054,7 @@ llvm::Constant *CodeGenModule::EmitAnnotationString(StringRef Str) {      true, llvm::GlobalValue::PrivateLinkage, s, ".str");    gv->setSection(AnnotationSection);    gv->setUnnamedAddr(true); -  AnnotationStrings[Str] = gv; +  AStr = gv;    return gv;  } @@ -998,18 +1114,9 @@ llvm::Constant *CodeGenModule::GetAddrOfUuidDescriptor(      const CXXUuidofExpr* E) {    // Sema has verified that IIDSource has a __declspec(uuid()), and that its    // well-formed. -  StringRef Uuid; -  if (E->isTypeOperand()) -    Uuid = CXXUuidofExpr::GetUuidAttrOfType(E->getTypeOperand())->getGuid(); -  else { -    // Special case: __uuidof(0) means an all-zero GUID. -    Expr *Op = E->getExprOperand(); -    if (!Op->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) -      Uuid = CXXUuidofExpr::GetUuidAttrOfType(Op->getType())->getGuid(); -    else -      Uuid = "00000000-0000-0000-0000-000000000000"; -  } -  std::string Name = "__uuid_" + Uuid.str(); +  StringRef Uuid = E->getUuidAsStringRef(Context); +  std::string Name = "_GUID_" + Uuid.lower(); +  std::replace(Name.begin(), Name.end(), '-', '_');    // Look for an existing global.    if (llvm::GlobalVariable *GV = getModule().getNamedGlobal(Name)) @@ -1018,22 +1125,9 @@ llvm::Constant *CodeGenModule::GetAddrOfUuidDescriptor(    llvm::Constant *Init = EmitUuidofInitializer(Uuid, E->getType());    assert(Init && "failed to initialize as constant"); -  // GUIDs are assumed to be 16 bytes, spread over 4-2-2-8 bytes. However, the -  // first field is declared as "long", which for many targets is 8 bytes. -  // Those architectures are not supported. (With the MS abi, long is always 4 -  // bytes.) -  llvm::Type *GuidType = getTypes().ConvertType(E->getType()); -  if (Init->getType() != GuidType) { -    DiagnosticsEngine &Diags = getDiags(); -    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, -        "__uuidof codegen is not supported on this architecture"); -    Diags.Report(E->getExprLoc(), DiagID) << E->getSourceRange(); -    Init = llvm::UndefValue::get(GuidType); -  } - -  llvm::GlobalVariable *GV = new llvm::GlobalVariable(getModule(), GuidType, -      /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, Init, Name); -  GV->setUnnamedAddr(true); +  llvm::GlobalVariable *GV = new llvm::GlobalVariable( +      getModule(), Init->getType(), +      /*isConstant=*/true, llvm::GlobalValue::LinkOnceODRLinkage, Init, Name);    return GV;  } @@ -1203,9 +1297,10 @@ CodeGenModule::isTriviallyRecursive(const FunctionDecl *FD) {  }  bool -CodeGenModule::shouldEmitFunction(const FunctionDecl *F) { -  if (getFunctionLinkage(F) != llvm::Function::AvailableExternallyLinkage) +CodeGenModule::shouldEmitFunction(GlobalDecl GD) { +  if (getFunctionLinkage(GD) != llvm::Function::AvailableExternallyLinkage)      return true; +  const FunctionDecl *F = cast<FunctionDecl>(GD.getDecl());    if (CodeGenOpts.OptimizationLevel == 0 &&        !F->hasAttr<AlwaysInlineAttr>() && !F->hasAttr<ForceInlineAttr>())      return false; @@ -1217,6 +1312,23 @@ CodeGenModule::shouldEmitFunction(const FunctionDecl *F) {    return !isTriviallyRecursive(F);  } +/// If the type for the method's class was generated by +/// CGDebugInfo::createContextChain(), the cache contains only a +/// limited DIType without any declarations. Since EmitFunctionStart() +/// needs to find the canonical declaration for each method, we need +/// to construct the complete type prior to emitting the method. +void CodeGenModule::CompleteDIClassType(const CXXMethodDecl* D) { +  if (!D->isInstance()) +    return; + +  if (CGDebugInfo *DI = getModuleDebugInfo()) +    if (getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo) { +      const PointerType *ThisPtr = +        cast<PointerType>(D->getThisType(getContext())); +      DI->getOrCreateRecordType(ThisPtr->getPointeeType(), D->getLocation()); +    } +} +  void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {    const ValueDecl *D = cast<ValueDecl>(GD.getDecl()); @@ -1224,13 +1336,14 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {                                   Context.getSourceManager(),                                   "Generating code for declaration"); -  if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { +  if (isa<FunctionDecl>(D)) {      // At -O0, don't generate IR for functions with available_externally       // linkage. -    if (!shouldEmitFunction(Function)) +    if (!shouldEmitFunction(GD))        return;      if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { +      CompleteDIClassType(Method);        // Make sure to emit the definition(s) before we emit the thunks.        // This is necessary for the generation of certain thunks.        if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Method)) @@ -1265,13 +1378,15 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {  llvm::Constant *  CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,                                         llvm::Type *Ty, -                                       GlobalDecl D, bool ForVTable, +                                       GlobalDecl GD, bool ForVTable,                                         llvm::AttributeSet ExtraAttrs) { +  const Decl *D = GD.getDecl(); +    // Lookup the entry, lazily creating it if necessary.    llvm::GlobalValue *Entry = GetGlobalValue(MangledName);    if (Entry) {      if (WeakRefReferences.erase(Entry)) { -      const FunctionDecl *FD = cast_or_null<FunctionDecl>(D.getDecl()); +      const FunctionDecl *FD = cast_or_null<FunctionDecl>(D);        if (FD && !FD->hasAttr<WeakAttr>())          Entry->setLinkage(llvm::Function::ExternalLinkage);      } @@ -1283,6 +1398,14 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,      return llvm::ConstantExpr::getBitCast(Entry, Ty->getPointerTo());    } +  // All MSVC dtors other than the base dtor are linkonce_odr and delegate to +  // each other bottoming out with the base dtor.  Therefore we emit non-base +  // dtors on usage, even if there is no dtor definition in the TU. +  if (D && isa<CXXDestructorDecl>(D) && +      getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D), +                                         GD.getDtorType())) +    DeferredDeclsToEmit.push_back(GD); +    // This function doesn't have a complete type (for example, the return    // type is an incomplete struct). Use a fake type instead, and make    // sure not to try to set attributes. @@ -1300,8 +1423,8 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,                                               llvm::Function::ExternalLinkage,                                               MangledName, &getModule());    assert(F->getName() == MangledName && "name was uniqued!"); -  if (D.getDecl()) -    SetFunctionAttributes(D, F, IsIncompleteFunction); +  if (D) +    SetFunctionAttributes(GD, F, IsIncompleteFunction);    if (ExtraAttrs.hasAttributes(llvm::AttributeSet::FunctionIndex)) {      llvm::AttrBuilder B(ExtraAttrs, llvm::AttributeSet::FunctionIndex);      F->addAttributes(llvm::AttributeSet::FunctionIndex, @@ -1320,6 +1443,12 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,      DeferredDeclsToEmit.push_back(DDI->second);      DeferredDecls.erase(DDI); +  // Otherwise, if this is a sized deallocation function, emit a weak definition +  // for it at the end of the translation unit. +  } else if (D && cast<FunctionDecl>(D) +                      ->getCorrespondingUnsizedGlobalDeallocationFunction()) { +    DeferredDeclsToEmit.push_back(GD); +    // Otherwise, there are cases we have to worry about where we're    // using a declaration for which we must emit a definition but where    // we might not find a top-level definition: @@ -1331,18 +1460,18 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,    //    // We also don't emit a definition for a function if it's going to be an entry    // in a vtable, unless it's already marked as used. -  } else if (getLangOpts().CPlusPlus && D.getDecl()) { +  } else if (getLangOpts().CPlusPlus && D) {      // Look for a declaration that's lexically in a record. -    const FunctionDecl *FD = cast<FunctionDecl>(D.getDecl()); +    const FunctionDecl *FD = cast<FunctionDecl>(D);      FD = FD->getMostRecentDecl();      do {        if (isa<CXXRecordDecl>(FD->getLexicalDeclContext())) {          if (FD->isImplicit() && !ForVTable) {            assert(FD->isUsed() && "Sema didn't mark implicit function as used!"); -          DeferredDeclsToEmit.push_back(D.getWithDecl(FD)); +          DeferredDeclsToEmit.push_back(GD.getWithDecl(FD));            break;          } else if (FD->doesThisDeclarationHaveABody()) { -          DeferredDeclsToEmit.push_back(D.getWithDecl(FD)); +          DeferredDeclsToEmit.push_back(GD.getWithDecl(FD));            break;          }        } @@ -1436,6 +1565,9 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,        return Entry;      // Make sure the result is of the correct type. +    if (Entry->getType()->getAddressSpace() != Ty->getAddressSpace()) +      return llvm::ConstantExpr::getAddrSpaceCast(Entry, Ty); +      return llvm::ConstantExpr::getBitCast(Entry, Ty);    } @@ -1483,12 +1615,19 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,          CXXThreadLocals.push_back(std::make_pair(D, GV));        setTLSMode(GV, *D);      } + +    // If required by the ABI, treat declarations of static data members with +    // inline initializers as definitions. +    if (getCXXABI().isInlineInitializedStaticDataMemberLinkOnce() && +        D->isStaticDataMember() && D->hasInit() && +        !D->isThisDeclarationADefinition()) +      EmitGlobalVarDefinition(D);    }    if (AddrSpace != Ty->getAddressSpace()) -    return llvm::ConstantExpr::getBitCast(GV, Ty); -  else -    return GV; +    return llvm::ConstantExpr::getAddrSpaceCast(GV, Ty); + +  return GV;  } @@ -1581,125 +1720,6 @@ CharUnits CodeGenModule::GetTargetTypeStoreSize(llvm::Type *Ty) const {        TheDataLayout.getTypeStoreSizeInBits(Ty));  } -llvm::Constant * -CodeGenModule::MaybeEmitGlobalStdInitializerListInitializer(const VarDecl *D, -                                                       const Expr *rawInit) { -  ArrayRef<ExprWithCleanups::CleanupObject> cleanups; -  if (const ExprWithCleanups *withCleanups = -          dyn_cast<ExprWithCleanups>(rawInit)) { -    cleanups = withCleanups->getObjects(); -    rawInit = withCleanups->getSubExpr(); -  } - -  const InitListExpr *init = dyn_cast<InitListExpr>(rawInit); -  if (!init || !init->initializesStdInitializerList() || -      init->getNumInits() == 0) -    return 0; - -  ASTContext &ctx = getContext(); -  unsigned numInits = init->getNumInits(); -  // FIXME: This check is here because we would otherwise silently miscompile -  // nested global std::initializer_lists. Better would be to have a real -  // implementation. -  for (unsigned i = 0; i < numInits; ++i) { -    const InitListExpr *inner = dyn_cast<InitListExpr>(init->getInit(i)); -    if (inner && inner->initializesStdInitializerList()) { -      ErrorUnsupported(inner, "nested global std::initializer_list"); -      return 0; -    } -  } - -  // Synthesize a fake VarDecl for the array and initialize that. -  QualType elementType = init->getInit(0)->getType(); -  llvm::APInt numElements(ctx.getTypeSize(ctx.getSizeType()), numInits); -  QualType arrayType = ctx.getConstantArrayType(elementType, numElements, -                                                ArrayType::Normal, 0); - -  IdentifierInfo *name = &ctx.Idents.get(D->getNameAsString() + "__initlist"); -  TypeSourceInfo *sourceInfo = ctx.getTrivialTypeSourceInfo( -                                              arrayType, D->getLocation()); -  VarDecl *backingArray = VarDecl::Create(ctx, const_cast<DeclContext*>( -                                                          D->getDeclContext()), -                                          D->getLocStart(), D->getLocation(), -                                          name, arrayType, sourceInfo, -                                          SC_Static); -  backingArray->setTSCSpec(D->getTSCSpec()); - -  // Now clone the InitListExpr to initialize the array instead. -  // Incredible hack: we want to use the existing InitListExpr here, so we need -  // to tell it that it no longer initializes a std::initializer_list. -  ArrayRef<Expr*> Inits(const_cast<InitListExpr*>(init)->getInits(), -                        init->getNumInits()); -  Expr *arrayInit = new (ctx) InitListExpr(ctx, init->getLBraceLoc(), Inits, -                                           init->getRBraceLoc()); -  arrayInit->setType(arrayType); - -  if (!cleanups.empty()) -    arrayInit = ExprWithCleanups::Create(ctx, arrayInit, cleanups); - -  backingArray->setInit(arrayInit); - -  // Emit the definition of the array. -  EmitGlobalVarDefinition(backingArray); - -  // Inspect the initializer list to validate it and determine its type. -  // FIXME: doing this every time is probably inefficient; caching would be nice -  RecordDecl *record = init->getType()->castAs<RecordType>()->getDecl(); -  RecordDecl::field_iterator field = record->field_begin(); -  if (field == record->field_end()) { -    ErrorUnsupported(D, "weird std::initializer_list"); -    return 0; -  } -  QualType elementPtr = ctx.getPointerType(elementType.withConst()); -  // Start pointer. -  if (!ctx.hasSameType(field->getType(), elementPtr)) { -    ErrorUnsupported(D, "weird std::initializer_list"); -    return 0; -  } -  ++field; -  if (field == record->field_end()) { -    ErrorUnsupported(D, "weird std::initializer_list"); -    return 0; -  } -  bool isStartEnd = false; -  if (ctx.hasSameType(field->getType(), elementPtr)) { -    // End pointer. -    isStartEnd = true; -  } else if(!ctx.hasSameType(field->getType(), ctx.getSizeType())) { -    ErrorUnsupported(D, "weird std::initializer_list"); -    return 0; -  } - -  // Now build an APValue representing the std::initializer_list. -  APValue initListValue(APValue::UninitStruct(), 0, 2); -  APValue &startField = initListValue.getStructField(0); -  APValue::LValuePathEntry startOffsetPathEntry; -  startOffsetPathEntry.ArrayIndex = 0; -  startField = APValue(APValue::LValueBase(backingArray), -                       CharUnits::fromQuantity(0), -                       llvm::makeArrayRef(startOffsetPathEntry), -                       /*IsOnePastTheEnd=*/false, 0); - -  if (isStartEnd) { -    APValue &endField = initListValue.getStructField(1); -    APValue::LValuePathEntry endOffsetPathEntry; -    endOffsetPathEntry.ArrayIndex = numInits; -    endField = APValue(APValue::LValueBase(backingArray), -                       ctx.getTypeSizeInChars(elementType) * numInits, -                       llvm::makeArrayRef(endOffsetPathEntry), -                       /*IsOnePastTheEnd=*/true, 0); -  } else { -    APValue &sizeField = initListValue.getStructField(1); -    sizeField = APValue(llvm::APSInt(numElements)); -  } - -  // Emit the constant for the initializer_list. -  llvm::Constant *llvmInit = -      EmitConstantValueForMemory(initListValue, D->getType()); -  assert(llvmInit && "failed to initialize as constant"); -  return llvmInit; -} -  unsigned CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D,                                                   unsigned AddrSpace) {    if (LangOpts.CUDA && CodeGenOpts.CUDAIsDevice) { @@ -1726,12 +1746,12 @@ void CodeGenModule::MaybeHandleStaticInExternC(const SomeDecl *D,      return;    // Must have internal linkage and an ordinary name. -  if (!D->getIdentifier() || D->getLinkage() != InternalLinkage) +  if (!D->getIdentifier() || D->getFormalLinkage() != InternalLinkage)      return;    // Must be in an extern "C" context. Entities declared directly within    // a record are not extern "C" even if the record is in such a context. -  const SomeDecl *First = D->getFirstDeclaration(); +  const SomeDecl *First = D->getFirstDecl();    if (First->getDeclContext()->isRecord() || !First->isInExternCContext())      return; @@ -1770,18 +1790,10 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {      assert(!ASTTy->isIncompleteType() && "Unexpected incomplete type");      Init = EmitNullConstant(D->getType());    } else { -    // If this is a std::initializer_list, emit the special initializer. -    Init = MaybeEmitGlobalStdInitializerListInitializer(D, InitExpr); -    // An empty init list will perform zero-initialization, which happens -    // to be exactly what we want. -    // FIXME: It does so in a global constructor, which is *not* what we -    // want. +    initializedGlobalDecl = GlobalDecl(D); +    Init = EmitConstantInit(*InitDecl);      if (!Init) { -      initializedGlobalDecl = GlobalDecl(D); -      Init = EmitConstantInit(*InitDecl); -    } -    if (!Init) {        QualType T = InitExpr->getType();        if (D->getType()->isReferenceType())          T = D->getType(); @@ -1808,7 +1820,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {    // Strip off a bitcast if we got one back.    if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {      assert(CE->getOpcode() == llvm::Instruction::BitCast || -           // all zero index gep. +           CE->getOpcode() == llvm::Instruction::AddrSpaceCast || +           // All zero index gep.             CE->getOpcode() == llvm::Instruction::GetElementPtr);      Entry = CE->getOperand(0);    } @@ -1860,8 +1873,16 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {    // Set the llvm linkage type as appropriate.    llvm::GlobalValue::LinkageTypes Linkage =  -    GetLLVMLinkageVarDefinition(D, GV); +    GetLLVMLinkageVarDefinition(D, GV->isConstant());    GV->setLinkage(Linkage); + +  // If required by the ABI, give definitions of static data members with inline +  // initializers linkonce_odr linkage. +  if (getCXXABI().isInlineInitializedStaticDataMemberLinkOnce() && +      D->isStaticDataMember() && InitExpr && +      !InitDecl->isThisDeclarationADefinition()) +    GV->setLinkage(llvm::GlobalVariable::LinkOnceODRLinkage); +    if (Linkage == llvm::GlobalVariable::CommonLinkage)      // common vars aren't constant even if declared const.      GV->setConstant(false); @@ -1891,8 +1912,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {  }  llvm::GlobalValue::LinkageTypes -CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D, -                                           llvm::GlobalVariable *GV) { +CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D, bool isConstant) {    GVALinkage Linkage = getContext().GetGVALinkageForVariable(D);    if (Linkage == GVA_Internal)      return llvm::Function::InternalLinkage; @@ -1900,8 +1920,14 @@ CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D,      return llvm::Function::DLLImportLinkage;    else if (D->hasAttr<DLLExportAttr>())      return llvm::Function::DLLExportLinkage; -  else if (D->hasAttr<WeakAttr>()) { -    if (GV->isConstant()) +  else if (D->hasAttr<SelectAnyAttr>()) { +    // selectany symbols are externally visible, so use weak instead of +    // linkonce.  MSVC optimizes away references to const selectany globals, so +    // all definitions should be the same and ODR linkage should be used. +    // http://msdn.microsoft.com/en-us/library/5tkz6s71.aspx +    return llvm::GlobalVariable::WeakODRLinkage; +  } else if (D->hasAttr<WeakAttr>()) { +    if (isConstant)        return llvm::GlobalVariable::WeakODRLinkage;      else        return llvm::GlobalVariable::WeakAnyLinkage; @@ -2077,6 +2103,10 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {      Entry = CE->getOperand(0);    } +  if (!cast<llvm::GlobalValue>(Entry)->isDeclaration()) { +    getDiags().Report(D->getLocation(), diag::err_duplicate_mangled_name); +    return; +  }    if (cast<llvm::GlobalValue>(Entry)->getType()->getElementType() != Ty) {      llvm::GlobalValue *OldFn = cast<llvm::GlobalValue>(Entry); @@ -2126,7 +2156,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {    // want to propagate this information down (e.g. to local static    // declarations).    llvm::Function *Fn = cast<llvm::Function>(Entry); -  setFunctionLinkage(D, Fn); +  setFunctionLinkage(GD, Fn);    // FIXME: this is redundant with part of SetFunctionDefinitionAttributes    setGlobalVisibility(Fn, D); @@ -2159,6 +2189,8 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {    if (Entry && !Entry->isDeclaration())      return; +  Aliases.push_back(GD); +    llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());    // Create a reference to the named value.  This ensures that it is emitted @@ -2624,11 +2656,16 @@ static llvm::GlobalVariable *GenerateStringLiteral(StringRef str,    llvm::Constant *C =        llvm::ConstantDataArray::getString(CGM.getLLVMContext(), str, false); +  // OpenCL v1.1 s6.5.3: a string literal is in the constant address space. +  unsigned AddrSpace = 0; +  if (CGM.getLangOpts().OpenCL) +    AddrSpace = CGM.getContext().getTargetAddressSpace(LangAS::opencl_constant); +    // Create a global variable for this string -  llvm::GlobalVariable *GV = -    new llvm::GlobalVariable(CGM.getModule(), C->getType(), constant, -                             llvm::GlobalValue::PrivateLinkage, -                             C, GlobalName); +  llvm::GlobalVariable *GV = new llvm::GlobalVariable( +      CGM.getModule(), C->getType(), constant, +      llvm::GlobalValue::PrivateLinkage, C, GlobalName, 0, +      llvm::GlobalVariable::NotThreadLocal, AddrSpace);    GV->setAlignment(Alignment);    GV->setUnnamedAddr(true);    return GV; @@ -2684,6 +2721,74 @@ llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &Str,    return GetAddrOfConstantString(StrWithNull, GlobalName, Alignment);  } +llvm::Constant *CodeGenModule::GetAddrOfGlobalTemporary( +    const MaterializeTemporaryExpr *E, const Expr *Init) { +  assert((E->getStorageDuration() == SD_Static || +          E->getStorageDuration() == SD_Thread) && "not a global temporary"); +  const VarDecl *VD = cast<VarDecl>(E->getExtendingDecl()); + +  // If we're not materializing a subobject of the temporary, keep the +  // cv-qualifiers from the type of the MaterializeTemporaryExpr. +  QualType MaterializedType = Init->getType(); +  if (Init == E->GetTemporaryExpr()) +    MaterializedType = E->getType(); + +  llvm::Constant *&Slot = MaterializedGlobalTemporaryMap[E]; +  if (Slot) +    return Slot; + +  // FIXME: If an externally-visible declaration extends multiple temporaries, +  // we need to give each temporary the same name in every translation unit (and +  // we also need to make the temporaries externally-visible). +  SmallString<256> Name; +  llvm::raw_svector_ostream Out(Name); +  getCXXABI().getMangleContext().mangleReferenceTemporary(VD, Out); +  Out.flush(); + +  APValue *Value = 0; +  if (E->getStorageDuration() == SD_Static) { +    // We might have a cached constant initializer for this temporary. Note +    // that this might have a different value from the value computed by +    // evaluating the initializer if the surrounding constant expression +    // modifies the temporary. +    Value = getContext().getMaterializedTemporaryValue(E, false); +    if (Value && Value->isUninit()) +      Value = 0; +  } + +  // Try evaluating it now, it might have a constant initializer. +  Expr::EvalResult EvalResult; +  if (!Value && Init->EvaluateAsRValue(EvalResult, getContext()) && +      !EvalResult.hasSideEffects()) +    Value = &EvalResult.Val; + +  llvm::Constant *InitialValue = 0; +  bool Constant = false; +  llvm::Type *Type; +  if (Value) { +    // The temporary has a constant initializer, use it. +    InitialValue = EmitConstantValue(*Value, MaterializedType, 0); +    Constant = isTypeConstant(MaterializedType, /*ExcludeCtor*/Value); +    Type = InitialValue->getType(); +  } else { +    // No initializer, the initialization will be provided when we +    // initialize the declaration which performed lifetime extension. +    Type = getTypes().ConvertTypeForMem(MaterializedType); +  } + +  // Create a global variable for this lifetime-extended temporary. +  llvm::GlobalVariable *GV = +    new llvm::GlobalVariable(getModule(), Type, Constant, +                             llvm::GlobalValue::PrivateLinkage, +                             InitialValue, Name.c_str()); +  GV->setAlignment( +      getContext().getTypeAlignInChars(MaterializedType).getQuantity()); +  if (VD->getTLSKind()) +    setTLSMode(GV, *VD); +  Slot = GV; +  return GV; +} +  /// EmitObjCPropertyImplementations - Emit information for synthesized  /// properties for an implementation.  void CodeGenModule::EmitObjCPropertyImplementations(const @@ -2767,8 +2872,13 @@ void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) {  /// EmitNamespace - Emit all declarations in a namespace.  void CodeGenModule::EmitNamespace(const NamespaceDecl *ND) {    for (RecordDecl::decl_iterator I = ND->decls_begin(), E = ND->decls_end(); -       I != E; ++I) +       I != E; ++I) { +    if (const VarDecl *VD = dyn_cast<VarDecl>(*I)) +      if (VD->getTemplateSpecializationKind() != TSK_ExplicitSpecialization && +          VD->getTemplateSpecializationKind() != TSK_Undeclared) +        continue;      EmitTopLevelDecl(*I); +  }  }  // EmitLinkageSpec - Emit all declarations in a linkage spec. @@ -2795,12 +2905,6 @@ void CodeGenModule::EmitLinkageSpec(const LinkageSpecDecl *LSD) {  /// EmitTopLevelDecl - Emit code for a single top level declaration.  void CodeGenModule::EmitTopLevelDecl(Decl *D) { -  // If an error has occurred, stop code generation, but continue -  // parsing and semantic analysis (to ensure all warnings and errors -  // are emitted). -  if (Diags.hasErrorOccurred()) -    return; -    // Ignore dependent declarations.    if (D->getDeclContext() && D->getDeclContext()->isDependentContext())      return; @@ -2816,8 +2920,12 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {      EmitGlobal(cast<FunctionDecl>(D));      break; -       +    case Decl::Var: +    // Skip variable templates +    if (cast<VarDecl>(D)->getDescribedVarTemplate()) +      return; +  case Decl::VarTemplateSpecialization:      EmitGlobal(cast<VarDecl>(D));      break; @@ -2834,12 +2942,17 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {    case Decl::UsingShadow:    case Decl::Using:    case Decl::ClassTemplate: +  case Decl::VarTemplate: +  case Decl::VarTemplatePartialSpecialization:    case Decl::FunctionTemplate:    case Decl::TypeAliasTemplate: -  case Decl::NamespaceAlias:    case Decl::Block:    case Decl::Empty:      break; +  case Decl::NamespaceAlias: +    if (CGDebugInfo *DI = getModuleDebugInfo()) +        DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(*D)); +    return;    case Decl::UsingDirective: // using namespace X; [C++]      if (CGDebugInfo *DI = getModuleDebugInfo())        DI->EmitUsingDirective(cast<UsingDirectiveDecl>(*D)); @@ -2850,12 +2963,12 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {          cast<FunctionDecl>(D)->isLateTemplateParsed())        return; -    EmitCXXConstructors(cast<CXXConstructorDecl>(D)); +    getCXXABI().EmitCXXConstructors(cast<CXXConstructorDecl>(D));      break;    case Decl::CXXDestructor:      if (cast<FunctionDecl>(D)->isLateTemplateParsed())        return; -    EmitCXXDestructors(cast<CXXDestructorDecl>(D)); +    getCXXABI().EmitCXXDestructors(cast<CXXDestructorDecl>(D));      break;    case Decl::StaticAssert: @@ -3032,6 +3145,18 @@ void CodeGenFunction::EmitDeclMetadata() {    }  } +void CodeGenModule::EmitVersionIdentMetadata() { +  llvm::NamedMDNode *IdentMetadata = +    TheModule.getOrInsertNamedMetadata("llvm.ident"); +  std::string Version = getClangFullVersion(); +  llvm::LLVMContext &Ctx = TheModule.getContext(); + +  llvm::Value *IdentNode[] = { +    llvm::MDString::get(Ctx, Version) +  }; +  IdentMetadata->addOperand(llvm::MDNode::get(Ctx, IdentNode)); +} +  void CodeGenModule::EmitCoverageFile() {    if (!getCodeGenOpts().CoverageFile.empty()) {      if (llvm::NamedMDNode *CUNode = TheModule.getNamedMetadata("llvm.dbg.cu")) { @@ -3054,26 +3179,24 @@ llvm::Constant *CodeGenModule::EmitUuidofInitializer(StringRef Uuid,    // Sema has checked that all uuid strings are of the form    // "12345678-1234-1234-1234-1234567890ab".    assert(Uuid.size() == 36); -  const char *Uuidstr = Uuid.data(); -  for (int i = 0; i < 36; ++i) { -    if (i == 8 || i == 13 || i == 18 || i == 23) assert(Uuidstr[i] == '-'); -    else                                         assert(isHexDigit(Uuidstr[i])); +  for (unsigned i = 0; i < 36; ++i) { +    if (i == 8 || i == 13 || i == 18 || i == 23) assert(Uuid[i] == '-'); +    else                                         assert(isHexDigit(Uuid[i]));    } -   -  llvm::APInt Field0(32, StringRef(Uuidstr     , 8), 16); -  llvm::APInt Field1(16, StringRef(Uuidstr +  9, 4), 16); -  llvm::APInt Field2(16, StringRef(Uuidstr + 14, 4), 16); -  static const int Field3ValueOffsets[] = { 19, 21, 24, 26, 28, 30, 32, 34 }; - -  APValue InitStruct(APValue::UninitStruct(), /*NumBases=*/0, /*NumFields=*/4); -  InitStruct.getStructField(0) = APValue(llvm::APSInt(Field0)); -  InitStruct.getStructField(1) = APValue(llvm::APSInt(Field1)); -  InitStruct.getStructField(2) = APValue(llvm::APSInt(Field2)); -  APValue& Arr = InitStruct.getStructField(3); -  Arr = APValue(APValue::UninitArray(), 8, 8); -  for (int t = 0; t < 8; ++t) -    Arr.getArrayInitializedElt(t) = APValue(llvm::APSInt( -          llvm::APInt(8, StringRef(Uuidstr + Field3ValueOffsets[t], 2), 16))); - -  return EmitConstantValue(InitStruct, GuidType); + +  const unsigned Field3ValueOffsets[8] = { 19, 21, 24, 26, 28, 30, 32, 34 }; + +  llvm::Constant *Field3[8]; +  for (unsigned Idx = 0; Idx < 8; ++Idx) +    Field3[Idx] = llvm::ConstantInt::get( +        Int8Ty, Uuid.substr(Field3ValueOffsets[Idx], 2), 16); + +  llvm::Constant *Fields[4] = { +    llvm::ConstantInt::get(Int32Ty, Uuid.substr(0,  8), 16), +    llvm::ConstantInt::get(Int16Ty, Uuid.substr(9,  4), 16), +    llvm::ConstantInt::get(Int16Ty, Uuid.substr(14, 4), 16), +    llvm::ConstantArray::get(llvm::ArrayType::get(Int8Ty, 8), Field3) +  }; + +  return llvm::ConstantStruct::getAnon(Fields);  } diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 91138c607c36b..c16122405d43f 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -31,7 +31,7 @@  #include "llvm/IR/CallingConv.h"  #include "llvm/IR/Module.h"  #include "llvm/Support/ValueHandle.h" -#include "llvm/Transforms/Utils/BlackList.h" +#include "llvm/Transforms/Utils/SpecialCaseList.h"  namespace llvm {    class Module; @@ -250,7 +250,6 @@ class CodeGenModule : public CodeGenTypeCache {    /// VTables - Holds information about C++ vtables.    CodeGenVTables VTables; -  friend class CodeGenVTables;    CGObjCRuntime* ObjCRuntime;    CGOpenCLRuntime* OpenCLRuntime; @@ -276,6 +275,13 @@ class CodeGenModule : public CodeGenTypeCache {    /// is done.    std::vector<GlobalDecl> DeferredDeclsToEmit; +  /// List of alias we have emitted. Used to make sure that what they point to +  /// is defined once we get to the end of the of the translation unit. +  std::vector<GlobalDecl> Aliases; + +  typedef llvm::StringMap<llvm::TrackingVH<llvm::Constant> > ReplacementsTy; +  ReplacementsTy Replacements; +    /// DeferredVTables - A queue of (optional) vtables to consider emitting.    std::vector<const CXXRecordDecl*> DeferredVTables; @@ -307,10 +313,14 @@ class CodeGenModule : public CodeGenTypeCache {    llvm::StringMap<llvm::GlobalVariable*> ConstantStringMap;    llvm::DenseMap<const Decl*, llvm::Constant *> StaticLocalDeclMap;    llvm::DenseMap<const Decl*, llvm::GlobalVariable*> StaticLocalDeclGuardMap; -   +  llvm::DenseMap<const Expr*, llvm::Constant *> MaterializedGlobalTemporaryMap; +    llvm::DenseMap<QualType, llvm::Constant *> AtomicSetterHelperFnMap;    llvm::DenseMap<QualType, llvm::Constant *> AtomicGetterHelperFnMap; +  /// Map used to get unique type descriptor constants for sanitizers. +  llvm::DenseMap<QualType, llvm::Constant *> TypeDescriptorMap; +    /// Map used to track internal linkage functions declared within    /// extern "C" regions.    typedef llvm::MapVector<IdentifierInfo *, @@ -355,6 +365,9 @@ class CodeGenModule : public CodeGenTypeCache {    /// \brief The complete set of modules that has been imported.    llvm::SetVector<clang::Module *> ImportedModules; +  /// \brief A vector of metadata strings. +  SmallVector<llvm::Value *, 16> LinkerOptionsMetadata; +    /// @name Cache for Objective-C runtime types    /// @{ @@ -382,7 +395,7 @@ class CodeGenModule : public CodeGenTypeCache {    void createCUDARuntime();    bool isTriviallyRecursive(const FunctionDecl *F); -  bool shouldEmitFunction(const FunctionDecl *F); +  bool shouldEmitFunction(GlobalDecl GD);    /// @name Cache for Blocks Runtime Globals    /// @{ @@ -408,7 +421,7 @@ class CodeGenModule : public CodeGenTypeCache {    GlobalDecl initializedGlobalDecl; -  llvm::BlackList SanitizerBlacklist; +  llvm::OwningPtr<llvm::SpecialCaseList> SanitizerBlacklist;    const SanitizerOptions &SanOpts; @@ -488,6 +501,13 @@ public:      AtomicGetterHelperFnMap[Ty] = Fn;    } +  llvm::Constant *getTypeDescriptor(QualType Ty) { +    return TypeDescriptorMap[Ty]; +  } +  void setTypeDescriptor(QualType Ty, llvm::Constant *C) { +    TypeDescriptorMap[Ty] = C; +  } +    CGDebugInfo *getModuleDebugInfo() { return DebugInfo; }    llvm::MDNode *getNoObjCARCExceptionsMetadata() { @@ -515,7 +535,14 @@ public:    CodeGenTypes &getTypes() { return Types; }    CodeGenVTables &getVTables() { return VTables; } -  VTableContext &getVTableContext() { return VTables.getVTableContext(); } + +  ItaniumVTableContext &getItaniumVTableContext() { +    return VTables.getItaniumVTableContext(); +  } + +  MicrosoftVTableContext &getMicrosoftVTableContext() { +    return VTables.getMicrosoftVTableContext(); +  }    llvm::MDNode *getTBAAInfo(QualType QTy);    llvm::MDNode *getTBAAInfoForVTablePtr(); @@ -728,7 +755,12 @@ public:    /// GetAddrOfConstantCompoundLiteral - Returns a pointer to a constant global    /// variable for the given file-scope compound literal expression.    llvm::Constant *GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E); -   + +  /// \brief Returns a pointer to a global variable representing a temporary +  /// with static or thread storage duration. +  llvm::Constant *GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E, +                                           const Expr *Inner); +    /// \brief Retrieve the record type that describes the state of an    /// Objective-C fast enumeration loop (for..in).    QualType getObjCFastEnumerationStateType(); @@ -743,7 +775,8 @@ public:    /// given type.    llvm::GlobalValue *GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor,                                              CXXDtorType dtorType, -                                            const CGFunctionInfo *fnInfo = 0); +                                            const CGFunctionInfo *fnInfo = 0, +                                            llvm::FunctionType *fnType = 0);    /// getBuiltinLibFunction - Given a builtin id for a function like    /// "__builtin_fabsf", return a Function* for "fabsf". @@ -842,17 +875,11 @@ public:    /// ErrorUnsupported - Print out an error that codegen doesn't support the    /// specified stmt yet. -  /// \param OmitOnError - If true, then this error should only be emitted if no -  /// other errors have been reported. -  void ErrorUnsupported(const Stmt *S, const char *Type, -                        bool OmitOnError=false); +  void ErrorUnsupported(const Stmt *S, const char *Type);    /// ErrorUnsupported - Print out an error that codegen doesn't support the    /// specified decl yet. -  /// \param OmitOnError - If true, then this error should only be emitted if no -  /// other errors have been reported. -  void ErrorUnsupported(const Decl *D, const char *Type, -                        bool OmitOnError=false); +  void ErrorUnsupported(const Decl *D, const char *Type);    /// SetInternalFunctionAttributes - Set the attributes on the LLVM    /// function for the given decl and function info. This applies @@ -906,11 +933,23 @@ public:    void EmitVTable(CXXRecordDecl *Class, bool DefinitionRequired); -  llvm::GlobalVariable::LinkageTypes -  getFunctionLinkage(const FunctionDecl *FD); +  /// EmitFundamentalRTTIDescriptors - Emit the RTTI descriptors for the +  /// builtin types. +  void EmitFundamentalRTTIDescriptors(); + +  /// \brief Appends Opts to the "Linker Options" metadata value. +  void AppendLinkerOptions(StringRef Opts); -  void setFunctionLinkage(const FunctionDecl *FD, llvm::GlobalValue *V) { -    V->setLinkage(getFunctionLinkage(FD)); +  /// \brief Appends a detect mismatch command to the linker options. +  void AddDetectMismatch(StringRef Name, StringRef Value); + +  /// \brief Appends a dependent lib to the "Linker Options" metadata value. +  void AddDependentLib(StringRef Lib); + +  llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD); + +  void setFunctionLinkage(GlobalDecl GD, llvm::GlobalValue *V) { +    V->setLinkage(getFunctionLinkage(GD));    }    /// getVTableLinkage - Return the appropriate linkage for the vtable, VTT, @@ -924,8 +963,7 @@ public:    /// GetLLVMLinkageVarDefinition - Returns LLVM linkage for a global     /// variable.    llvm::GlobalValue::LinkageTypes  -  GetLLVMLinkageVarDefinition(const VarDecl *D, -                              llvm::GlobalVariable *GV); +  GetLLVMLinkageVarDefinition(const VarDecl *D, bool isConstant);    /// Emit all the global annotations.    void EmitGlobalAnnotations(); @@ -954,8 +992,8 @@ public:    /// annotations are emitted during finalization of the LLVM code.    void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV); -  const llvm::BlackList &getSanitizerBlacklist() const { -    return SanitizerBlacklist; +  const llvm::SpecialCaseList &getSanitizerBlacklist() const { +    return *SanitizerBlacklist;    }    const SanitizerOptions &getSanOpts() const { return SanOpts; } @@ -964,6 +1002,10 @@ public:      DeferredVTables.push_back(RD);    } +  /// EmitGlobal - Emit code for a singal global function or var decl. Forward +  /// declarations are emitted lazily. +  void EmitGlobal(GlobalDecl D); +  private:    llvm::GlobalValue *GetGlobalValue(StringRef Ref); @@ -995,40 +1037,28 @@ private:                               llvm::Function *F,                               bool IsIncompleteFunction); -  /// EmitGlobal - Emit code for a singal global function or var decl. Forward -  /// declarations are emitted lazily. -  void EmitGlobal(GlobalDecl D); -    void EmitGlobalDefinition(GlobalDecl D);    void EmitGlobalFunctionDefinition(GlobalDecl GD);    void EmitGlobalVarDefinition(const VarDecl *D); -  llvm::Constant *MaybeEmitGlobalStdInitializerListInitializer(const VarDecl *D, -                                                              const Expr *init);    void EmitAliasDefinition(GlobalDecl GD);    void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);    void EmitObjCIvarInitializations(ObjCImplementationDecl *D);    // C++ related functions. -  bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target); +  bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target, +                                bool InEveryTU);    bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);    void EmitNamespace(const NamespaceDecl *D);    void EmitLinkageSpec(const LinkageSpecDecl *D); - -  /// EmitCXXConstructors - Emit constructors (base, complete) from a -  /// C++ constructor Decl. -  void EmitCXXConstructors(const CXXConstructorDecl *D); +  void CompleteDIClassType(const CXXMethodDecl* D);    /// EmitCXXConstructor - Emit a single constructor with the given type from    /// a C++ constructor Decl.    void EmitCXXConstructor(const CXXConstructorDecl *D, CXXCtorType Type); -  /// EmitCXXDestructors - Emit destructors (base, complete) from a -  /// C++ destructor Decl. -  void EmitCXXDestructors(const CXXDestructorDecl *D); -    /// EmitCXXDestructor - Emit a single destructor with the given type from    /// a C++ destructor Decl.    void EmitCXXDestructor(const CXXDestructorDecl *D, CXXDtorType Type); @@ -1061,14 +1091,15 @@ private:    /// given type.    void EmitFundamentalRTTIDescriptor(QualType Type); -  /// EmitFundamentalRTTIDescriptors - Emit the RTTI descriptors for the -  /// builtin types. -  void EmitFundamentalRTTIDescriptors(); -    /// EmitDeferred - Emit any needed decls for which code generation    /// was deferred.    void EmitDeferred(); +  /// Call replaceAllUsesWith on all pairs in Replacements. +  void applyReplacements(); + +  void checkAliases(); +    /// EmitDeferredVTables - Emit any vtables which we deferred and    /// still have a use for.    void EmitDeferredVTables(); @@ -1086,6 +1117,9 @@ private:    void EmitDeclMetadata(); +  /// \brief Emit the Clang version as llvm.ident metadata. +  void EmitVersionIdentMetadata(); +    /// EmitCoverageFile - Emit the llvm.gcov metadata used to tell LLVM where    /// to emit the .gcno and .gcda files in a way that persists in .bc files.    void EmitCoverageFile(); diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp index 5ff1560a48867..699cc2eabe184 100644 --- a/lib/CodeGen/CodeGenTBAA.cpp +++ b/lib/CodeGen/CodeGenTBAA.cpp @@ -50,16 +50,11 @@ llvm::MDNode *CodeGenTBAA::getRoot() {    return Root;  } -// For struct-path aware TBAA, the scalar type has the same format as -// the struct type: name, offset, pointer to another node in the type DAG. -// For scalar TBAA, the scalar type is the same as the scalar tag: -// name and a parent pointer. +// For both scalar TBAA and struct-path aware TBAA, the scalar type has the +// same format: name, parent node, and offset.  llvm::MDNode *CodeGenTBAA::createTBAAScalarType(StringRef Name,                                                  llvm::MDNode *Parent) { -  if (CodeGenOpts.StructPathTBAA) -    return MDHelper.createTBAAScalarTypeNode(Name, Parent); -  else -    return MDHelper.createTBAANode(Name, Parent); +  return MDHelper.createTBAAScalarTypeNode(Name, Parent);  }  llvm::MDNode *CodeGenTBAA::getChar() { @@ -91,7 +86,7 @@ static bool TypeHasMayAlias(QualType QTy) {  llvm::MDNode *  CodeGenTBAA::getTBAAInfo(QualType QTy) { -  // At -O0 TBAA is not emitted for regular types. +  // At -O0 or relaxed aliasing, TBAA is not emitted for regular types.    if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)      return NULL; @@ -150,27 +145,16 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) {    // Enum types are distinct types. In C++ they have "underlying types",    // however they aren't related for TBAA.    if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) { -    // In C mode, two anonymous enums are compatible iff their members -    // are the same -- see C99 6.2.7p1. For now, be conservative. We could -    // theoretically implement this by combining information about all the -    // members into a single identifying MDNode. -    if (!Features.CPlusPlus && -        ETy->getDecl()->getTypedefNameForAnonDecl()) -      return MetadataCache[Ty] = getChar(); -      // In C++ mode, types have linkage, so we can rely on the ODR and      // on their mangled names, if they're external.      // TODO: Is there a way to get a program-wide unique name for a      // decl with local linkage or no linkage? -    if (Features.CPlusPlus && -        ETy->getDecl()->getLinkage() != ExternalLinkage) +    if (!Features.CPlusPlus || !ETy->getDecl()->isExternallyVisible())        return MetadataCache[Ty] = getChar(); -    // TODO: This is using the RTTI name. Is there a better way to get -    // a unique string for a type?      SmallString<256> OutName;      llvm::raw_svector_ostream Out(OutName); -    MContext.mangleCXXRTTIName(QualType(ETy, 0), Out); +    MContext.mangleTypeName(QualType(ETy, 0), Out);      Out.flush();      return MetadataCache[Ty] = createTBAAScalarType(OutName, getChar());    } @@ -204,18 +188,8 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,      const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);      unsigned idx = 0; -    const FieldDecl *LastFD = 0; -    bool IsMsStruct = RD->isMsStruct(Context);      for (RecordDecl::field_iterator i = RD->field_begin(),           e = RD->field_end(); i != e; ++i, ++idx) { -      if (IsMsStruct) { -        // Zero-length bitfields following non-bitfield members are ignored. -        if (Context.ZeroBitfieldFollowsNonBitfield(*i, LastFD)) { -          --idx; -          continue; -        } -        LastFD = *i; -      }        uint64_t Offset = BaseOffset +                          Layout.getFieldOffset(idx) / Context.getCharWidth();        QualType FieldQTy = i->getType(); @@ -230,8 +204,7 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,    uint64_t Offset = BaseOffset;    uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity();    llvm::MDNode *TBAAInfo = MayAlias ? getChar() : getTBAAInfo(QTy); -  llvm::MDNode *TBAATag = CodeGenOpts.StructPathTBAA ? -                          getTBAAScalarTagInfo(TBAAInfo) : TBAAInfo; +  llvm::MDNode *TBAATag = getTBAAScalarTagInfo(TBAAInfo);    Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));    return true;  } @@ -279,19 +252,8 @@ CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) {      const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);      SmallVector <std::pair<llvm::MDNode*, uint64_t>, 4> Fields;      unsigned idx = 0; -    const FieldDecl *LastFD = 0; -    bool IsMsStruct = RD->isMsStruct(Context);      for (RecordDecl::field_iterator i = RD->field_begin(),           e = RD->field_end(); i != e; ++i, ++idx) { -      if (IsMsStruct) { -        // Zero-length bitfields following non-bitfield members are ignored. -        if (Context.ZeroBitfieldFollowsNonBitfield(*i, LastFD)) { -          --idx; -          continue; -        } -        LastFD = *i; -      } -        QualType FieldQTy = i->getType();        llvm::MDNode *FieldNode;        if (isTBAAPathStruct(FieldQTy)) @@ -304,12 +266,15 @@ CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) {            FieldNode, Layout.getFieldOffset(idx) / Context.getCharWidth()));      } -    // TODO: This is using the RTTI name. Is there a better way to get -    // a unique string for a type?      SmallString<256> OutName; -    llvm::raw_svector_ostream Out(OutName); -    MContext.mangleCXXRTTIName(QualType(Ty, 0), Out); -    Out.flush(); +    if (Features.CPlusPlus) { +      // Don't use the mangler for C code. +      llvm::raw_svector_ostream Out(OutName); +      MContext.mangleTypeName(QualType(Ty, 0), Out); +      Out.flush(); +    } else { +      OutName = RD->getName(); +    }      // Create the struct type node with a vector of pairs (offset, type).      return StructTypeMetadataCache[Ty] =        MDHelper.createTBAAStructTypeNode(OutName, Fields); @@ -318,11 +283,15 @@ CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) {    return StructMetadataCache[Ty] = NULL;  } +/// Return a TBAA tag node for both scalar TBAA and struct-path aware TBAA.  llvm::MDNode *  CodeGenTBAA::getTBAAStructTagInfo(QualType BaseQTy, llvm::MDNode *AccessNode,                                    uint64_t Offset) { +  if (!AccessNode) +    return NULL; +    if (!CodeGenOpts.StructPathTBAA) -    return AccessNode; +    return getTBAAScalarTagInfo(AccessNode);    const Type *BTy = Context.getCanonicalType(BaseQTy).getTypePtr();    TBAAPathTag PathTag = TBAAPathTag(BTy, AccessNode, Offset); @@ -342,6 +311,8 @@ CodeGenTBAA::getTBAAStructTagInfo(QualType BaseQTy, llvm::MDNode *AccessNode,  llvm::MDNode *  CodeGenTBAA::getTBAAScalarTagInfo(llvm::MDNode *AccessNode) { +  if (!AccessNode) +    return NULL;    if (llvm::MDNode *N = ScalarTagMetadataCache[AccessNode])      return N; diff --git a/lib/CodeGen/CodeGenTBAA.h b/lib/CodeGen/CodeGenTBAA.h index f0c9e06f02bdd..0ad4be24fd246 100644 --- a/lib/CodeGen/CodeGenTBAA.h +++ b/lib/CodeGen/CodeGenTBAA.h @@ -117,7 +117,7 @@ public:    llvm::MDNode *getTBAAStructTagInfo(QualType BaseQType,                                       llvm::MDNode *AccessNode, uint64_t Offset); -  /// Get the sclar tag MDNode for a given scalar type. +  /// Get the scalar tag MDNode for a given scalar type.    llvm::MDNode *getTBAAScalarTagInfo(llvm::MDNode *AccessNode);  }; diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index 4240216b230c6..5f3c59c197a64 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -22,6 +22,7 @@  #include "clang/AST/DeclObjC.h"  #include "clang/AST/Expr.h"  #include "clang/AST/RecordLayout.h" +#include "clang/CodeGen/CGFunctionInfo.h"  #include "llvm/IR/DataLayout.h"  #include "llvm/IR/DerivedTypes.h"  #include "llvm/IR/Module.h" @@ -32,7 +33,6 @@ CodeGenTypes::CodeGenTypes(CodeGenModule &cgm)    : CGM(cgm), Context(cgm.getContext()), TheModule(cgm.getModule()),      TheDataLayout(cgm.getDataLayout()),      Target(cgm.getTarget()), TheCXXABI(cgm.getCXXABI()), -    CodeGenOpts(cgm.getCodeGenOpts()),      TheABIInfo(cgm.getTargetCodeGenInfo().getABIInfo()) {    SkippedLayout = false;  } @@ -260,6 +260,11 @@ void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) {    // yet, we'll just do it lazily.    if (RecordDeclTypes.count(Context.getTagDeclType(RD).getTypePtr()))      ConvertRecordDeclType(RD); + +  // If necessary, provide the full definition of a type only used with a +  // declaration so far. +  if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) +    DI->completeType(RD);  }  static llvm::Type *getTypeForFormat(llvm::LLVMContext &VMContext, diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h index 452375f374c43..94ca9e21e5fe8 100644 --- a/lib/CodeGen/CodeGenTypes.h +++ b/lib/CodeGen/CodeGenTypes.h @@ -16,6 +16,7 @@  #include "CGCall.h"  #include "clang/AST/GlobalDecl.h" +#include "clang/CodeGen/CGFunctionInfo.h"  #include "llvm/ADT/DenseMap.h"  #include "llvm/IR/Module.h"  #include <vector> @@ -58,21 +59,18 @@ namespace CodeGen {  /// CodeGenTypes - This class organizes the cross-module state that is used  /// while lowering AST types to LLVM types.  class CodeGenTypes { -public: -  // Some of this stuff should probably be left on the CGM.    CodeGenModule &CGM; +  // Some of this stuff should probably be left on the CGM.    ASTContext &Context;    llvm::Module &TheModule;    const llvm::DataLayout &TheDataLayout;    const TargetInfo &Target;    CGCXXABI &TheCXXABI; -  const CodeGenOptions &CodeGenOpts;    // This should not be moved earlier, since its initialization depends on some    // of the previous reference members being already initialized    const ABIInfo &TheABIInfo; -private:    /// The opaque type map for Objective-C interfaces. All direct    /// manipulation is done by the runtime interfaces, which are    /// responsible for coercing to the appropriate type; these opaque @@ -116,7 +114,6 @@ public:    const llvm::DataLayout &getDataLayout() const { return TheDataLayout; }    ASTContext &getContext() const { return Context; }    const ABIInfo &getABIInfo() const { return TheABIInfo; } -  const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }    const TargetInfo &getTarget() const { return Target; }    CGCXXABI &getCXXABI() const { return TheCXXABI; }    llvm::LLVMContext &getLLVMContext() { return TheModule.getContext(); } diff --git a/lib/CodeGen/EHScopeStack.h b/lib/CodeGen/EHScopeStack.h new file mode 100644 index 0000000000000..e9d9a339ffc70 --- /dev/null +++ b/lib/CodeGen/EHScopeStack.h @@ -0,0 +1,489 @@ +//===-- EHScopeStack.h - Stack for cleanup IR generation --------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// These classes should be the minimum interface required for other parts of +// CodeGen to emit cleanups.  The implementation is in CGCleanup.cpp and other +// implemenentation details that are not widely needed are in CGCleanup.h. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_CODEGEN_EHSCOPESTACK_H +#define CLANG_CODEGEN_EHSCOPESTACK_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Value.h" +#include "llvm/IR/Instructions.h" + +namespace clang { +namespace CodeGen { + +class CodeGenFunction; + +/// A branch fixup.  These are required when emitting a goto to a +/// label which hasn't been emitted yet.  The goto is optimistically +/// emitted as a branch to the basic block for the label, and (if it +/// occurs in a scope with non-trivial cleanups) a fixup is added to +/// the innermost cleanup.  When a (normal) cleanup is popped, any +/// unresolved fixups in that scope are threaded through the cleanup. +struct BranchFixup { +  /// The block containing the terminator which needs to be modified +  /// into a switch if this fixup is resolved into the current scope. +  /// If null, LatestBranch points directly to the destination. +  llvm::BasicBlock *OptimisticBranchBlock; + +  /// The ultimate destination of the branch. +  /// +  /// This can be set to null to indicate that this fixup was +  /// successfully resolved. +  llvm::BasicBlock *Destination; + +  /// The destination index value. +  unsigned DestinationIndex; + +  /// The initial branch of the fixup. +  llvm::BranchInst *InitialBranch; +}; + +template <class T> struct InvariantValue { +  typedef T type; +  typedef T saved_type; +  static bool needsSaving(type value) { return false; } +  static saved_type save(CodeGenFunction &CGF, type value) { return value; } +  static type restore(CodeGenFunction &CGF, saved_type value) { return value; } +}; + +/// A metaprogramming class for ensuring that a value will dominate an +/// arbitrary position in a function. +template <class T> struct DominatingValue : InvariantValue<T> {}; + +template <class T, bool mightBeInstruction = +            llvm::is_base_of<llvm::Value, T>::value && +            !llvm::is_base_of<llvm::Constant, T>::value && +            !llvm::is_base_of<llvm::BasicBlock, T>::value> +struct DominatingPointer; +template <class T> struct DominatingPointer<T,false> : InvariantValue<T*> {}; +// template <class T> struct DominatingPointer<T,true> at end of file + +template <class T> struct DominatingValue<T*> : DominatingPointer<T> {}; + +enum CleanupKind { +  EHCleanup = 0x1, +  NormalCleanup = 0x2, +  NormalAndEHCleanup = EHCleanup | NormalCleanup, + +  InactiveCleanup = 0x4, +  InactiveEHCleanup = EHCleanup | InactiveCleanup, +  InactiveNormalCleanup = NormalCleanup | InactiveCleanup, +  InactiveNormalAndEHCleanup = NormalAndEHCleanup | InactiveCleanup +}; + +/// A stack of scopes which respond to exceptions, including cleanups +/// and catch blocks. +class EHScopeStack { +public: +  /// A saved depth on the scope stack.  This is necessary because +  /// pushing scopes onto the stack invalidates iterators. +  class stable_iterator { +    friend class EHScopeStack; + +    /// Offset from StartOfData to EndOfBuffer. +    ptrdiff_t Size; + +    stable_iterator(ptrdiff_t Size) : Size(Size) {} + +  public: +    static stable_iterator invalid() { return stable_iterator(-1); } +    stable_iterator() : Size(-1) {} + +    bool isValid() const { return Size >= 0; } + +    /// Returns true if this scope encloses I. +    /// Returns false if I is invalid. +    /// This scope must be valid. +    bool encloses(stable_iterator I) const { return Size <= I.Size; } + +    /// Returns true if this scope strictly encloses I: that is, +    /// if it encloses I and is not I. +    /// Returns false is I is invalid. +    /// This scope must be valid. +    bool strictlyEncloses(stable_iterator I) const { return Size < I.Size; } + +    friend bool operator==(stable_iterator A, stable_iterator B) { +      return A.Size == B.Size; +    } +    friend bool operator!=(stable_iterator A, stable_iterator B) { +      return A.Size != B.Size; +    } +  }; + +  /// Information for lazily generating a cleanup.  Subclasses must be +  /// POD-like: cleanups will not be destructed, and they will be +  /// allocated on the cleanup stack and freely copied and moved +  /// around. +  /// +  /// Cleanup implementations should generally be declared in an +  /// anonymous namespace. +  class Cleanup { +    // Anchor the construction vtable. +    virtual void anchor(); +  public: +    /// Generation flags. +    class Flags { +      enum { +        F_IsForEH             = 0x1, +        F_IsNormalCleanupKind = 0x2, +        F_IsEHCleanupKind     = 0x4 +      }; +      unsigned flags; + +    public: +      Flags() : flags(0) {} + +      /// isForEH - true if the current emission is for an EH cleanup. +      bool isForEHCleanup() const { return flags & F_IsForEH; } +      bool isForNormalCleanup() const { return !isForEHCleanup(); } +      void setIsForEHCleanup() { flags |= F_IsForEH; } + +      bool isNormalCleanupKind() const { return flags & F_IsNormalCleanupKind; } +      void setIsNormalCleanupKind() { flags |= F_IsNormalCleanupKind; } + +      /// isEHCleanupKind - true if the cleanup was pushed as an EH +      /// cleanup. +      bool isEHCleanupKind() const { return flags & F_IsEHCleanupKind; } +      void setIsEHCleanupKind() { flags |= F_IsEHCleanupKind; } +    }; + +    // Provide a virtual destructor to suppress a very common warning +    // that unfortunately cannot be suppressed without this.  Cleanups +    // should not rely on this destructor ever being called. +    virtual ~Cleanup() {} + +    /// Emit the cleanup.  For normal cleanups, this is run in the +    /// same EH context as when the cleanup was pushed, i.e. the +    /// immediately-enclosing context of the cleanup scope.  For +    /// EH cleanups, this is run in a terminate context. +    /// +    // \param flags cleanup kind. +    virtual void Emit(CodeGenFunction &CGF, Flags flags) = 0; +  }; + +  /// ConditionalCleanupN stores the saved form of its N parameters, +  /// then restores them and performs the cleanup. +  template <class T, class A0> +  class ConditionalCleanup1 : public Cleanup { +    typedef typename DominatingValue<A0>::saved_type A0_saved; +    A0_saved a0_saved; + +    void Emit(CodeGenFunction &CGF, Flags flags) { +      A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved); +      T(a0).Emit(CGF, flags); +    } + +  public: +    ConditionalCleanup1(A0_saved a0) +      : a0_saved(a0) {} +  }; + +  template <class T, class A0, class A1> +  class ConditionalCleanup2 : public Cleanup { +    typedef typename DominatingValue<A0>::saved_type A0_saved; +    typedef typename DominatingValue<A1>::saved_type A1_saved; +    A0_saved a0_saved; +    A1_saved a1_saved; + +    void Emit(CodeGenFunction &CGF, Flags flags) { +      A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved); +      A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved); +      T(a0, a1).Emit(CGF, flags); +    } + +  public: +    ConditionalCleanup2(A0_saved a0, A1_saved a1) +      : a0_saved(a0), a1_saved(a1) {} +  }; + +  template <class T, class A0, class A1, class A2> +  class ConditionalCleanup3 : public Cleanup { +    typedef typename DominatingValue<A0>::saved_type A0_saved; +    typedef typename DominatingValue<A1>::saved_type A1_saved; +    typedef typename DominatingValue<A2>::saved_type A2_saved; +    A0_saved a0_saved; +    A1_saved a1_saved; +    A2_saved a2_saved; + +    void Emit(CodeGenFunction &CGF, Flags flags) { +      A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved); +      A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved); +      A2 a2 = DominatingValue<A2>::restore(CGF, a2_saved); +      T(a0, a1, a2).Emit(CGF, flags); +    } + +  public: +    ConditionalCleanup3(A0_saved a0, A1_saved a1, A2_saved a2) +      : a0_saved(a0), a1_saved(a1), a2_saved(a2) {} +  }; + +  template <class T, class A0, class A1, class A2, class A3> +  class ConditionalCleanup4 : public Cleanup { +    typedef typename DominatingValue<A0>::saved_type A0_saved; +    typedef typename DominatingValue<A1>::saved_type A1_saved; +    typedef typename DominatingValue<A2>::saved_type A2_saved; +    typedef typename DominatingValue<A3>::saved_type A3_saved; +    A0_saved a0_saved; +    A1_saved a1_saved; +    A2_saved a2_saved; +    A3_saved a3_saved; + +    void Emit(CodeGenFunction &CGF, Flags flags) { +      A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved); +      A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved); +      A2 a2 = DominatingValue<A2>::restore(CGF, a2_saved); +      A3 a3 = DominatingValue<A3>::restore(CGF, a3_saved); +      T(a0, a1, a2, a3).Emit(CGF, flags); +    } + +  public: +    ConditionalCleanup4(A0_saved a0, A1_saved a1, A2_saved a2, A3_saved a3) +      : a0_saved(a0), a1_saved(a1), a2_saved(a2), a3_saved(a3) {} +  }; + +private: +  // The implementation for this class is in CGException.h and +  // CGException.cpp; the definition is here because it's used as a +  // member of CodeGenFunction. + +  /// The start of the scope-stack buffer, i.e. the allocated pointer +  /// for the buffer.  All of these pointers are either simultaneously +  /// null or simultaneously valid. +  char *StartOfBuffer; + +  /// The end of the buffer. +  char *EndOfBuffer; + +  /// The first valid entry in the buffer. +  char *StartOfData; + +  /// The innermost normal cleanup on the stack. +  stable_iterator InnermostNormalCleanup; + +  /// The innermost EH scope on the stack. +  stable_iterator InnermostEHScope; + +  /// The current set of branch fixups.  A branch fixup is a jump to +  /// an as-yet unemitted label, i.e. a label for which we don't yet +  /// know the EH stack depth.  Whenever we pop a cleanup, we have +  /// to thread all the current branch fixups through it. +  /// +  /// Fixups are recorded as the Use of the respective branch or +  /// switch statement.  The use points to the final destination. +  /// When popping out of a cleanup, these uses are threaded through +  /// the cleanup and adjusted to point to the new cleanup. +  /// +  /// Note that branches are allowed to jump into protected scopes +  /// in certain situations;  e.g. the following code is legal: +  ///     struct A { ~A(); }; // trivial ctor, non-trivial dtor +  ///     goto foo; +  ///     A a; +  ///    foo: +  ///     bar(); +  SmallVector<BranchFixup, 8> BranchFixups; + +  char *allocate(size_t Size); + +  void *pushCleanup(CleanupKind K, size_t DataSize); + +public: +  EHScopeStack() : StartOfBuffer(0), EndOfBuffer(0), StartOfData(0), +                   InnermostNormalCleanup(stable_end()), +                   InnermostEHScope(stable_end()) {} +  ~EHScopeStack() { delete[] StartOfBuffer; } + +  // Variadic templates would make this not terrible. + +  /// Push a lazily-created cleanup on the stack. +  template <class T> +  void pushCleanup(CleanupKind Kind) { +    void *Buffer = pushCleanup(Kind, sizeof(T)); +    Cleanup *Obj = new(Buffer) T(); +    (void) Obj; +  } + +  /// Push a lazily-created cleanup on the stack. +  template <class T, class A0> +  void pushCleanup(CleanupKind Kind, A0 a0) { +    void *Buffer = pushCleanup(Kind, sizeof(T)); +    Cleanup *Obj = new(Buffer) T(a0); +    (void) Obj; +  } + +  /// Push a lazily-created cleanup on the stack. +  template <class T, class A0, class A1> +  void pushCleanup(CleanupKind Kind, A0 a0, A1 a1) { +    void *Buffer = pushCleanup(Kind, sizeof(T)); +    Cleanup *Obj = new(Buffer) T(a0, a1); +    (void) Obj; +  } + +  /// Push a lazily-created cleanup on the stack. +  template <class T, class A0, class A1, class A2> +  void pushCleanup(CleanupKind Kind, A0 a0, A1 a1, A2 a2) { +    void *Buffer = pushCleanup(Kind, sizeof(T)); +    Cleanup *Obj = new(Buffer) T(a0, a1, a2); +    (void) Obj; +  } + +  /// Push a lazily-created cleanup on the stack. +  template <class T, class A0, class A1, class A2, class A3> +  void pushCleanup(CleanupKind Kind, A0 a0, A1 a1, A2 a2, A3 a3) { +    void *Buffer = pushCleanup(Kind, sizeof(T)); +    Cleanup *Obj = new(Buffer) T(a0, a1, a2, a3); +    (void) Obj; +  } + +  /// Push a lazily-created cleanup on the stack. +  template <class T, class A0, class A1, class A2, class A3, class A4> +  void pushCleanup(CleanupKind Kind, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { +    void *Buffer = pushCleanup(Kind, sizeof(T)); +    Cleanup *Obj = new(Buffer) T(a0, a1, a2, a3, a4); +    (void) Obj; +  } + +  // Feel free to add more variants of the following: + +  /// Push a cleanup with non-constant storage requirements on the +  /// stack.  The cleanup type must provide an additional static method: +  ///   static size_t getExtraSize(size_t); +  /// The argument to this method will be the value N, which will also +  /// be passed as the first argument to the constructor. +  /// +  /// The data stored in the extra storage must obey the same +  /// restrictions as normal cleanup member data. +  /// +  /// The pointer returned from this method is valid until the cleanup +  /// stack is modified. +  template <class T, class A0, class A1, class A2> +  T *pushCleanupWithExtra(CleanupKind Kind, size_t N, A0 a0, A1 a1, A2 a2) { +    void *Buffer = pushCleanup(Kind, sizeof(T) + T::getExtraSize(N)); +    return new (Buffer) T(N, a0, a1, a2); +  } + +  void pushCopyOfCleanup(CleanupKind Kind, const void *Cleanup, size_t Size) { +    void *Buffer = pushCleanup(Kind, Size); +    std::memcpy(Buffer, Cleanup, Size); +  } + +  /// Pops a cleanup scope off the stack.  This is private to CGCleanup.cpp. +  void popCleanup(); + +  /// Push a set of catch handlers on the stack.  The catch is +  /// uninitialized and will need to have the given number of handlers +  /// set on it. +  class EHCatchScope *pushCatch(unsigned NumHandlers); + +  /// Pops a catch scope off the stack.  This is private to CGException.cpp. +  void popCatch(); + +  /// Push an exceptions filter on the stack. +  class EHFilterScope *pushFilter(unsigned NumFilters); + +  /// Pops an exceptions filter off the stack. +  void popFilter(); + +  /// Push a terminate handler on the stack. +  void pushTerminate(); + +  /// Pops a terminate handler off the stack. +  void popTerminate(); + +  /// Determines whether the exception-scopes stack is empty. +  bool empty() const { return StartOfData == EndOfBuffer; } + +  bool requiresLandingPad() const { +    return InnermostEHScope != stable_end(); +  } + +  /// Determines whether there are any normal cleanups on the stack. +  bool hasNormalCleanups() const { +    return InnermostNormalCleanup != stable_end(); +  } + +  /// Returns the innermost normal cleanup on the stack, or +  /// stable_end() if there are no normal cleanups. +  stable_iterator getInnermostNormalCleanup() const { +    return InnermostNormalCleanup; +  } +  stable_iterator getInnermostActiveNormalCleanup() const; + +  stable_iterator getInnermostEHScope() const { +    return InnermostEHScope; +  } + +  stable_iterator getInnermostActiveEHScope() const; + +  /// An unstable reference to a scope-stack depth.  Invalidated by +  /// pushes but not pops. +  class iterator; + +  /// Returns an iterator pointing to the innermost EH scope. +  iterator begin() const; + +  /// Returns an iterator pointing to the outermost EH scope. +  iterator end() const; + +  /// Create a stable reference to the top of the EH stack.  The +  /// returned reference is valid until that scope is popped off the +  /// stack. +  stable_iterator stable_begin() const { +    return stable_iterator(EndOfBuffer - StartOfData); +  } + +  /// Create a stable reference to the bottom of the EH stack. +  static stable_iterator stable_end() { +    return stable_iterator(0); +  } + +  /// Translates an iterator into a stable_iterator. +  stable_iterator stabilize(iterator it) const; + +  /// Turn a stable reference to a scope depth into a unstable pointer +  /// to the EH stack. +  iterator find(stable_iterator save) const; + +  /// Removes the cleanup pointed to by the given stable_iterator. +  void removeCleanup(stable_iterator save); + +  /// Add a branch fixup to the current cleanup scope. +  BranchFixup &addBranchFixup() { +    assert(hasNormalCleanups() && "adding fixup in scope without cleanups"); +    BranchFixups.push_back(BranchFixup()); +    return BranchFixups.back(); +  } + +  unsigned getNumBranchFixups() const { return BranchFixups.size(); } +  BranchFixup &getBranchFixup(unsigned I) { +    assert(I < getNumBranchFixups()); +    return BranchFixups[I]; +  } + +  /// Pops lazily-removed fixups from the end of the list.  This +  /// should only be called by procedures which have just popped a +  /// cleanup or resolved one or more fixups. +  void popNullFixups(); + +  /// Clears the branch-fixups list.  This should only be called by +  /// ResolveAllBranchFixups. +  void clearFixups() { BranchFixups.clear(); } +}; + +} // namespace CodeGen +} // namespace clang + +#endif diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index e117e2867bdd9..0e8f31a48454a 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -34,12 +34,23 @@ using namespace CodeGen;  namespace {  class ItaniumCXXABI : public CodeGen::CGCXXABI { +  /// VTables - All the vtables which have been defined. +  llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables; +  protected: -  bool IsARM; +  bool UseARMMethodPtrABI; +  bool UseARMGuardVarABI; + +  ItaniumMangleContext &getMangleContext() { +    return cast<ItaniumMangleContext>(CodeGen::CGCXXABI::getMangleContext()); +  }  public: -  ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) : -    CGCXXABI(CGM), IsARM(IsARM) { } +  ItaniumCXXABI(CodeGen::CodeGenModule &CGM, +                bool UseARMMethodPtrABI = false, +                bool UseARMGuardVarABI = false) : +    CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI), +    UseARMGuardVarABI(UseARMGuardVarABI) { }    bool isReturnTypeIndirect(const CXXRecordDecl *RD) const {      // Structures with either a non-trivial destructor or a non-trivial @@ -98,36 +109,82 @@ public:                                        llvm::Value *ptr,                                        QualType type); +  llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF, +                                         llvm::Value *This, +                                         const CXXRecordDecl *ClassDecl, +                                         const CXXRecordDecl *BaseClassDecl); +    void BuildConstructorSignature(const CXXConstructorDecl *Ctor,                                   CXXCtorType T,                                   CanQualType &ResTy,                                   SmallVectorImpl<CanQualType> &ArgTys); +  void EmitCXXConstructors(const CXXConstructorDecl *D); +    void BuildDestructorSignature(const CXXDestructorDecl *Dtor,                                  CXXDtorType T,                                  CanQualType &ResTy,                                  SmallVectorImpl<CanQualType> &ArgTys); +  bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, +                              CXXDtorType DT) const { +    // Itanium does not emit any destructor variant as an inline thunk. +    // Delegating may occur as an optimization, but all variants are either +    // emitted with external linkage or as linkonce if they are inline and used. +    return false; +  } + +  void EmitCXXDestructors(const CXXDestructorDecl *D); +    void BuildInstanceFunctionParams(CodeGenFunction &CGF,                                     QualType &ResTy,                                     FunctionArgList &Params);    void EmitInstanceFunctionProlog(CodeGenFunction &CGF); -  llvm::Value *EmitConstructorCall(CodeGenFunction &CGF, -                           const CXXConstructorDecl *D, -                           CXXCtorType Type, bool ForVirtualBase, -                           bool Delegating, +  void EmitConstructorCall(CodeGenFunction &CGF, +                           const CXXConstructorDecl *D, CXXCtorType Type, +                           bool ForVirtualBase, bool Delegating,                             llvm::Value *This,                             CallExpr::const_arg_iterator ArgBeg,                             CallExpr::const_arg_iterator ArgEnd); -  RValue EmitVirtualDestructorCall(CodeGenFunction &CGF, -                                   const CXXDestructorDecl *Dtor, -                                   CXXDtorType DtorType, -                                   SourceLocation CallLoc, -                                   ReturnValueSlot ReturnValue, -                                   llvm::Value *This); +  void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD); + +  llvm::Value *getVTableAddressPointInStructor( +      CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, +      BaseSubobject Base, const CXXRecordDecl *NearestVBase, +      bool &NeedsVirtualOffset); + +  llvm::Constant * +  getVTableAddressPointForConstExpr(BaseSubobject Base, +                                    const CXXRecordDecl *VTableClass); + +  llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, +                                        CharUnits VPtrOffset); + +  llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, +                                         llvm::Value *This, llvm::Type *Ty); + +  void EmitVirtualDestructorCall(CodeGenFunction &CGF, +                                 const CXXDestructorDecl *Dtor, +                                 CXXDtorType DtorType, SourceLocation CallLoc, +                                 llvm::Value *This); + +  void emitVirtualInheritanceTables(const CXXRecordDecl *RD); + +  void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) { +    // Allow inlining of thunks by emitting them with available_externally +    // linkage together with vtables when needed. +    if (ForVTable) +      Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage); +  } + +  llvm::Value *performThisAdjustment(CodeGenFunction &CGF, llvm::Value *This, +                                     const ThisAdjustment &TA); + +  llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, llvm::Value *Ret, +                                       const ReturnAdjustment &RA);    StringRef GetPureVirtualCallName() { return "__cxa_pure_virtual"; }    StringRef GetDeletedVirtualCallName() { return "__cxa_deleted_virtual"; } @@ -154,27 +211,21 @@ public:        llvm::Function *InitFunc);    LValue EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,                                      const DeclRefExpr *DRE); + +  bool NeedsVTTParameter(GlobalDecl GD);  };  class ARMCXXABI : public ItaniumCXXABI {  public: -  ARMCXXABI(CodeGen::CodeGenModule &CGM) : ItaniumCXXABI(CGM, /*ARM*/ true) {} +  ARMCXXABI(CodeGen::CodeGenModule &CGM) : +    ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true, +                  /* UseARMGuardVarABI = */ true) {} -  void BuildConstructorSignature(const CXXConstructorDecl *Ctor, -                                 CXXCtorType T, -                                 CanQualType &ResTy, -                                 SmallVectorImpl<CanQualType> &ArgTys); - -  void BuildDestructorSignature(const CXXDestructorDecl *Dtor, -                                CXXDtorType T, -                                CanQualType &ResTy, -                                SmallVectorImpl<CanQualType> &ArgTys); - -  void BuildInstanceFunctionParams(CodeGenFunction &CGF, -                                   QualType &ResTy, -                                   FunctionArgList &Params); - -  void EmitInstanceFunctionProlog(CodeGenFunction &CGF); +  bool HasThisReturn(GlobalDecl GD) const { +    return (isa<CXXConstructorDecl>(GD.getDecl()) || ( +              isa<CXXDestructorDecl>(GD.getDecl()) && +              GD.getDtorType() != Dtor_Deleting)); +  }    void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResTy); @@ -186,15 +237,6 @@ public:                                       QualType ElementType);    llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, llvm::Value *allocPtr,                                     CharUnits cookieSize); - -  /// \brief Returns true if the given instance method is one of the -  /// kinds that the ARM ABI says returns 'this'. -  bool HasThisReturn(GlobalDecl GD) const { -    const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(GD.getDecl()); -    if (!MD) return false; -    return ((isa<CXXDestructorDecl>(MD) && GD.getDtorType() != Dtor_Deleting) || -            (isa<CXXConstructorDecl>(MD))); -  }  };  } @@ -210,9 +252,18 @@ CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) {    // include the other 32-bit ARM oddities: constructor/destructor return values    // and array cookies.    case TargetCXXABI::GenericAArch64: -    return  new ItaniumCXXABI(CGM, /*IsARM = */ true); +    return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true, +                             /* UseARMGuardVarABI = */ true);    case TargetCXXABI::GenericItanium: +    if (CGM.getContext().getTargetInfo().getTriple().getArch() +        == llvm::Triple::le32) { +      // For PNaCl, use ARM-style method pointers so that PNaCl code +      // does not assume anything about the alignment of function +      // pointers. +      return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true, +                               /* UseARMGuardVarABI = */ false); +    }      return new ItaniumCXXABI(CGM);    case TargetCXXABI::Microsoft: @@ -275,7 +326,7 @@ ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,    // Compute the true adjustment.    llvm::Value *Adj = RawAdj; -  if (IsARM) +  if (UseARMMethodPtrABI)      Adj = Builder.CreateAShr(Adj, ptrdiff_1, "memptr.adj.shifted");    // Apply the adjustment and cast back to the original struct type @@ -290,7 +341,7 @@ ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,    // If the LSB in the function pointer is 1, the function pointer points to    // a virtual function.    llvm::Value *IsVirtual; -  if (IsARM) +  if (UseARMMethodPtrABI)      IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);    else      IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1); @@ -309,7 +360,8 @@ ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,    // Apply the offset.    llvm::Value *VTableOffset = FnAsInt; -  if (!IsARM) VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1); +  if (!UseARMMethodPtrABI) +    VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);    VTable = Builder.CreateGEP(VTable, VTableOffset);    // Load the virtual function to call. @@ -419,7 +471,7 @@ ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,    }    // The this-adjustment is left-shifted by 1 on ARM. -  if (IsARM) { +  if (UseARMMethodPtrABI) {      uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();      offset <<= 1;      adj = llvm::ConstantInt::get(adj->getType(), offset); @@ -467,7 +519,7 @@ ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E,    }    // The this-adjustment is left-shifted by 1 on ARM. -  if (IsARM) { +  if (UseARMMethodPtrABI) {      uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();      offset <<= 1;      adj = llvm::ConstantInt::get(adj->getType(), offset); @@ -518,14 +570,14 @@ llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD,    // Get the function pointer (or index if this is a virtual function).    llvm::Constant *MemPtr[2];    if (MD->isVirtual()) { -    uint64_t Index = CGM.getVTableContext().getMethodVTableIndex(MD); +    uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);      const ASTContext &Context = getContext();      CharUnits PointerWidth =        Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));      uint64_t VTableOffset = (Index * PointerWidth.getQuantity()); -    if (IsARM) { +    if (UseARMMethodPtrABI) {        // ARM C++ ABI 3.2.1:        //   This ABI specifies that adj contains twice the this        //   adjustment, plus 1 if the member function is virtual. The @@ -559,7 +611,8 @@ llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD,      llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);      MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy); -    MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, (IsARM ? 2 : 1) * +    MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, +                                       (UseARMMethodPtrABI ? 2 : 1) *                                         ThisAdjustment.getQuantity());    } @@ -573,22 +626,7 @@ llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP,    if (!MPD)      return EmitNullMemberPointer(MPT); -  // Compute the this-adjustment. -  CharUnits ThisAdjustment = CharUnits::Zero(); -  ArrayRef<const CXXRecordDecl*> Path = MP.getMemberPointerPath(); -  bool DerivedMember = MP.isMemberPointerToDerivedMember(); -  const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPD->getDeclContext()); -  for (unsigned I = 0, N = Path.size(); I != N; ++I) { -    const CXXRecordDecl *Base = RD; -    const CXXRecordDecl *Derived = Path[I]; -    if (DerivedMember) -      std::swap(Base, Derived); -    ThisAdjustment += -      getContext().getASTRecordLayout(Derived).getBaseClassOffset(Base); -    RD = Path[I]; -  } -  if (DerivedMember) -    ThisAdjustment = -ThisAdjustment; +  CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP);    if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD))      return BuildMemberPointer(MD, ThisAdjustment); @@ -658,7 +696,7 @@ ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,    // Null member function pointers on ARM clear the low bit of Adj,    // so the zero condition has to check that neither low bit is set. -  if (IsARM) { +  if (UseARMMethodPtrABI) {      llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);      // Compute (l.adj | r.adj) & 1 and test it against zero. @@ -698,7 +736,7 @@ ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,    // On ARM, a member function pointer is also non-null if the low bit of 'adj'    // (the virtual bit) is set. -  if (IsARM) { +  if (UseARMMethodPtrABI) {      llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);      llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj");      llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit"); @@ -735,6 +773,28 @@ llvm::Value *ItaniumCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,    return CGF.Builder.CreateInBoundsGEP(ptr, offset);  } +llvm::Value * +ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF, +                                         llvm::Value *This, +                                         const CXXRecordDecl *ClassDecl, +                                         const CXXRecordDecl *BaseClassDecl) { +  llvm::Value *VTablePtr = CGF.GetVTablePtr(This, CGM.Int8PtrTy); +  CharUnits VBaseOffsetOffset = +      CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl, +                                                               BaseClassDecl); + +  llvm::Value *VBaseOffsetPtr = +    CGF.Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset.getQuantity(), +                                   "vbase.offset.ptr"); +  VBaseOffsetPtr = CGF.Builder.CreateBitCast(VBaseOffsetPtr, +                                             CGM.PtrDiffTy->getPointerTo()); + +  llvm::Value *VBaseOffset = +    CGF.Builder.CreateLoad(VBaseOffsetPtr, "vbase.offset"); + +  return VBaseOffset; +} +  /// The generic ABI passes 'this', plus a VTT if it's initializing a  /// base subobject.  void ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor, @@ -743,20 +803,28 @@ void ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,                                  SmallVectorImpl<CanQualType> &ArgTys) {    ASTContext &Context = getContext(); -  // 'this' is already there. +  // 'this' parameter is already there, as well as 'this' return if +  // HasThisReturn(GlobalDecl(Ctor, Type)) is true    // Check if we need to add a VTT parameter (which has type void **).    if (Type == Ctor_Base && Ctor->getParent()->getNumVBases() != 0)      ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));  } -/// The ARM ABI does the same as the Itanium ABI, but returns 'this'. -void ARMCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor, -                                          CXXCtorType Type, -                                          CanQualType &ResTy, -                                SmallVectorImpl<CanQualType> &ArgTys) { -  ItaniumCXXABI::BuildConstructorSignature(Ctor, Type, ResTy, ArgTys); -  ResTy = ArgTys[0]; +void ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) { +  // Just make sure we're in sync with TargetCXXABI. +  assert(CGM.getTarget().getCXXABI().hasConstructorVariants()); + +  // The constructor used for constructing this as a complete class; +  // constucts the virtual bases, then calls the base constructor. +  if (!D->getParent()->isAbstract()) { +    // We don't need to emit the complete ctor if the class is abstract. +    CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete)); +  } + +  // The constructor used for constructing this as a base class; +  // ignores virtual bases. +  CGM.EmitGlobal(GlobalDecl(D, Ctor_Base));  }  /// The generic ABI passes 'this', plus a VTT if it's destroying a @@ -767,23 +835,28 @@ void ItaniumCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,                                  SmallVectorImpl<CanQualType> &ArgTys) {    ASTContext &Context = getContext(); -  // 'this' is already there. +  // 'this' parameter is already there, as well as 'this' return if +  // HasThisReturn(GlobalDecl(Dtor, Type)) is true    // Check if we need to add a VTT parameter (which has type void **).    if (Type == Dtor_Base && Dtor->getParent()->getNumVBases() != 0)      ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));  } -/// The ARM ABI does the same as the Itanium ABI, but returns 'this' -/// for non-deleting destructors. -void ARMCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor, -                                         CXXDtorType Type, -                                         CanQualType &ResTy, -                                SmallVectorImpl<CanQualType> &ArgTys) { -  ItaniumCXXABI::BuildDestructorSignature(Dtor, Type, ResTy, ArgTys); +void ItaniumCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) { +  // The destructor in a virtual table is always a 'deleting' +  // destructor, which calls the complete destructor and then uses the +  // appropriate operator delete. +  if (D->isVirtual()) +    CGM.EmitGlobal(GlobalDecl(D, Dtor_Deleting)); + +  // The destructor used for destructing this as a most-derived class; +  // call the base destructor and then destructs any virtual bases. +  CGM.EmitGlobal(GlobalDecl(D, Dtor_Complete)); -  if (Type != Dtor_Deleting) -    ResTy = ArgTys[0]; +  // The destructor used for destructing this as a base class; ignores +  // virtual bases. +  CGM.EmitGlobal(GlobalDecl(D, Dtor_Base));  }  void ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF, @@ -796,7 +869,7 @@ void ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,    assert(MD->isInstance());    // Check if we need a VTT parameter as well. -  if (CodeGenVTables::needsVTTParameter(CGF.CurGD)) { +  if (NeedsVTTParameter(CGF.CurGD)) {      ASTContext &Context = getContext();      // FIXME: avoid the fake decl @@ -809,16 +882,6 @@ void ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,    }  } -void ARMCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF, -                                            QualType &ResTy, -                                            FunctionArgList &Params) { -  ItaniumCXXABI::BuildInstanceFunctionParams(CGF, ResTy, Params); - -  // Return 'this' from certain constructors and destructors. -  if (HasThisReturn(CGF.CurGD)) -    ResTy = Params[0]->getType(); -} -  void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {    /// Initialize the 'this' slot.    EmitThisParam(CGF); @@ -829,21 +892,23 @@ void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {        = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getVTTDecl(CGF)),                                 "vtt");    } -} -void ARMCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) { -  ItaniumCXXABI::EmitInstanceFunctionProlog(CGF); - -  /// Initialize the return slot to 'this' at the start of the -  /// function. +  /// If this is a function that the ABI specifies returns 'this', initialize +  /// the return slot to 'this' at the start of the function. +  /// +  /// Unlike the setting of return types, this is done within the ABI +  /// implementation instead of by clients of CGCXXABI because: +  /// 1) getThisValue is currently protected +  /// 2) in theory, an ABI could implement 'this' returns some other way; +  ///    HasThisReturn only specifies a contract, not the implementation    if (HasThisReturn(CGF.CurGD))      CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);  } -llvm::Value *ItaniumCXXABI::EmitConstructorCall(CodeGenFunction &CGF, +void ItaniumCXXABI::EmitConstructorCall(CodeGenFunction &CGF,                                          const CXXConstructorDecl *D, -                                        CXXCtorType Type, bool ForVirtualBase, -                                        bool Delegating, +                                        CXXCtorType Type, +                                        bool ForVirtualBase, bool Delegating,                                          llvm::Value *This,                                          CallExpr::const_arg_iterator ArgBeg,                                          CallExpr::const_arg_iterator ArgEnd) { @@ -853,26 +918,217 @@ llvm::Value *ItaniumCXXABI::EmitConstructorCall(CodeGenFunction &CGF,    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);    // FIXME: Provide a source location here. -  CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This, -                        VTT, VTTTy, ArgBeg, ArgEnd); -  return Callee; +  CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), +                        This, VTT, VTTTy, ArgBeg, ArgEnd); +} + +void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, +                                          const CXXRecordDecl *RD) { +  llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits()); +  if (VTable->hasInitializer()) +    return; + +  ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext(); +  const VTableLayout &VTLayout = VTContext.getVTableLayout(RD); +  llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD); + +  // Create and set the initializer. +  llvm::Constant *Init = CGVT.CreateVTableInitializer( +      RD, VTLayout.vtable_component_begin(), VTLayout.getNumVTableComponents(), +      VTLayout.vtable_thunk_begin(), VTLayout.getNumVTableThunks()); +  VTable->setInitializer(Init); + +  // Set the correct linkage. +  VTable->setLinkage(Linkage); + +  // Set the right visibility. +  CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForVTable); + +  // If this is the magic class __cxxabiv1::__fundamental_type_info, +  // we will emit the typeinfo for the fundamental types. This is the +  // same behaviour as GCC. +  const DeclContext *DC = RD->getDeclContext(); +  if (RD->getIdentifier() && +      RD->getIdentifier()->isStr("__fundamental_type_info") && +      isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() && +      cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") && +      DC->getParent()->isTranslationUnit()) +    CGM.EmitFundamentalRTTIDescriptors(); +} + +llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor( +    CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base, +    const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) { +  bool NeedsVTTParam = CGM.getCXXABI().NeedsVTTParameter(CGF.CurGD); +  NeedsVirtualOffset = (NeedsVTTParam && NearestVBase); + +  llvm::Value *VTableAddressPoint; +  if (NeedsVTTParam && (Base.getBase()->getNumVBases() || NearestVBase)) { +    // Get the secondary vpointer index. +    uint64_t VirtualPointerIndex = +        CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base); + +    /// Load the VTT. +    llvm::Value *VTT = CGF.LoadCXXVTT(); +    if (VirtualPointerIndex) +      VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex); + +    // And load the address point from the VTT. +    VTableAddressPoint = CGF.Builder.CreateLoad(VTT); +  } else { +    llvm::Constant *VTable = +        CGM.getCXXABI().getAddrOfVTable(VTableClass, CharUnits()); +    uint64_t AddressPoint = CGM.getItaniumVTableContext() +                                .getVTableLayout(VTableClass) +                                .getAddressPoint(Base); +    VTableAddressPoint = +        CGF.Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint); +  } + +  return VTableAddressPoint;  } -RValue ItaniumCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF, -                                                const CXXDestructorDecl *Dtor, -                                                CXXDtorType DtorType, -                                                SourceLocation CallLoc, -                                                ReturnValueSlot ReturnValue, -                                                llvm::Value *This) { +llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr( +    BaseSubobject Base, const CXXRecordDecl *VTableClass) { +  llvm::Constant *VTable = getAddrOfVTable(VTableClass, CharUnits()); + +  // Find the appropriate vtable within the vtable group. +  uint64_t AddressPoint = CGM.getItaniumVTableContext() +                              .getVTableLayout(VTableClass) +                              .getAddressPoint(Base); +  llvm::Value *Indices[] = { +    llvm::ConstantInt::get(CGM.Int64Ty, 0), +    llvm::ConstantInt::get(CGM.Int64Ty, AddressPoint) +  }; + +  return llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Indices); +} + +llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, +                                                     CharUnits VPtrOffset) { +  assert(VPtrOffset.isZero() && "Itanium ABI only supports zero vptr offsets"); + +  llvm::GlobalVariable *&VTable = VTables[RD]; +  if (VTable) +    return VTable; + +  // Queue up this v-table for possible deferred emission. +  CGM.addDeferredVTable(RD); + +  SmallString<256> OutName; +  llvm::raw_svector_ostream Out(OutName); +  getMangleContext().mangleCXXVTable(RD, Out); +  Out.flush(); +  StringRef Name = OutName.str(); + +  ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext(); +  llvm::ArrayType *ArrayType = llvm::ArrayType::get( +      CGM.Int8PtrTy, VTContext.getVTableLayout(RD).getNumVTableComponents()); + +  VTable = CGM.CreateOrReplaceCXXRuntimeVariable( +      Name, ArrayType, llvm::GlobalValue::ExternalLinkage); +  VTable->setUnnamedAddr(true); +  return VTable; +} + +llvm::Value *ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, +                                                      GlobalDecl GD, +                                                      llvm::Value *This, +                                                      llvm::Type *Ty) { +  GD = GD.getCanonicalDecl(); +  Ty = Ty->getPointerTo()->getPointerTo(); +  llvm::Value *VTable = CGF.GetVTablePtr(This, Ty); + +  uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD); +  llvm::Value *VFuncPtr = +      CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn"); +  return CGF.Builder.CreateLoad(VFuncPtr); +} + +void ItaniumCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF, +                                              const CXXDestructorDecl *Dtor, +                                              CXXDtorType DtorType, +                                              SourceLocation CallLoc, +                                              llvm::Value *This) {    assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);    const CGFunctionInfo *FInfo      = &CGM.getTypes().arrangeCXXDestructor(Dtor, DtorType);    llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); -  llvm::Value *Callee = CGF.BuildVirtualCall(Dtor, DtorType, This, Ty); +  llvm::Value *Callee = +      getVirtualFunctionPointer(CGF, GlobalDecl(Dtor, DtorType), This, Ty); -  return CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValue, This, -                               /*ImplicitParam=*/0, QualType(), 0, 0); +  CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValueSlot(), This, +                        /*ImplicitParam=*/0, QualType(), 0, 0); +} + +void ItaniumCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) { +  CodeGenVTables &VTables = CGM.getVTables(); +  llvm::GlobalVariable *VTT = VTables.GetAddrOfVTT(RD); +  VTables.EmitVTTDefinition(VTT, CGM.getVTableLinkage(RD), RD); +} + +static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF, +                                          llvm::Value *Ptr, +                                          int64_t NonVirtualAdjustment, +                                          int64_t VirtualAdjustment, +                                          bool IsReturnAdjustment) { +  if (!NonVirtualAdjustment && !VirtualAdjustment) +    return Ptr; + +  llvm::Type *Int8PtrTy = CGF.Int8PtrTy; +  llvm::Value *V = CGF.Builder.CreateBitCast(Ptr, Int8PtrTy); + +  if (NonVirtualAdjustment && !IsReturnAdjustment) { +    // Perform the non-virtual adjustment for a base-to-derived cast. +    V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment); +  } + +  if (VirtualAdjustment) { +    llvm::Type *PtrDiffTy = +        CGF.ConvertType(CGF.getContext().getPointerDiffType()); + +    // Perform the virtual adjustment. +    llvm::Value *VTablePtrPtr = +        CGF.Builder.CreateBitCast(V, Int8PtrTy->getPointerTo()); + +    llvm::Value *VTablePtr = CGF.Builder.CreateLoad(VTablePtrPtr); + +    llvm::Value *OffsetPtr = +        CGF.Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment); + +    OffsetPtr = CGF.Builder.CreateBitCast(OffsetPtr, PtrDiffTy->getPointerTo()); + +    // Load the adjustment offset from the vtable. +    llvm::Value *Offset = CGF.Builder.CreateLoad(OffsetPtr); + +    // Adjust our pointer. +    V = CGF.Builder.CreateInBoundsGEP(V, Offset); +  } + +  if (NonVirtualAdjustment && IsReturnAdjustment) { +    // Perform the non-virtual adjustment for a derived-to-base cast. +    V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment); +  } + +  // Cast back to the original type. +  return CGF.Builder.CreateBitCast(V, Ptr->getType()); +} + +llvm::Value *ItaniumCXXABI::performThisAdjustment(CodeGenFunction &CGF, +                                                  llvm::Value *This, +                                                  const ThisAdjustment &TA) { +  return performTypeAdjustment(CGF, This, TA.NonVirtual, +                               TA.Virtual.Itanium.VCallOffsetOffset, +                               /*IsReturnAdjustment=*/false); +} + +llvm::Value * +ItaniumCXXABI::performReturnAdjustment(CodeGenFunction &CGF, llvm::Value *Ret, +                                       const ReturnAdjustment &RA) { +  return performTypeAdjustment(CGF, Ret, RA.NonVirtual, +                               RA.Virtual.Itanium.VBaseOffsetOffset, +                               /*IsReturnAdjustment=*/true);  }  void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF, @@ -1079,7 +1335,7 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,    } else {      // Guard variables are 64 bits in the generic ABI and size width on ARM      // (i.e. 32-bit on AArch32, 64-bit on AArch64). -    guardTy = (IsARM ? CGF.SizeTy : CGF.Int64Ty); +    guardTy = (UseARMGuardVarABI ? CGF.SizeTy : CGF.Int64Ty);    }    llvm::PointerType *guardPtrTy = guardTy->getPointerTo(); @@ -1091,7 +1347,7 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,      SmallString<256> guardName;      {        llvm::raw_svector_ostream out(guardName); -      getMangleContext().mangleItaniumGuardVariable(&D, out); +      getMangleContext().mangleStaticGuardVariable(&D, out);        out.flush();      } @@ -1122,7 +1378,7 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,    //       if (__cxa_guard_acquire(&obj_guard))    //         ...    //     } -  if (IsARM && !useInt8GuardVariable) { +  if (UseARMGuardVarABI && !useInt8GuardVariable) {      llvm::Value *V = Builder.CreateLoad(guard);      llvm::Value *Test1 = llvm::ConstantInt::get(guardTy, 1);      V = Builder.CreateAnd(V, Test1); @@ -1259,7 +1515,7 @@ void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,      return CGM.AddCXXDtorEntry(dtor, addr);    } -  CGF.registerGlobalDtorWithAtExit(dtor, addr); +  CGF.registerGlobalDtorWithAtExit(D, dtor, addr);  }  /// Get the appropriate linkage for the wrapper function. This is essentially @@ -1396,3 +1652,23 @@ LValue ItaniumCXXABI::EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,    // FIXME: need setObjCGCLValueClass?    return LV;  } + +/// Return whether the given global decl needs a VTT parameter, which it does +/// if it's a base constructor or destructor with virtual bases. +bool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) { +  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); +   +  // We don't have any virtual bases, just return early. +  if (!MD->getParent()->getNumVBases()) +    return false; +   +  // Check if we have a base constructor. +  if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base) +    return true; + +  // Check if we have a base destructor. +  if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) +    return true; +   +  return false; +} diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index f5242eaaa2fb6..7318fe72a3c34 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -16,8 +16,12 @@  #include "CGCXXABI.h"  #include "CodeGenModule.h" +#include "CGVTables.h" +#include "MicrosoftVBTables.h"  #include "clang/AST/Decl.h"  #include "clang/AST/DeclCXX.h" +#include "clang/AST/VTableBuilder.h" +#include "llvm/ADT/StringSet.h"  using namespace clang;  using namespace CodeGen; @@ -28,13 +32,15 @@ class MicrosoftCXXABI : public CGCXXABI {  public:    MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {} +  bool HasThisReturn(GlobalDecl GD) const; +    bool isReturnTypeIndirect(const CXXRecordDecl *RD) const {      // Structures that are not C++03 PODs are always indirect.      return !RD->isPOD();    }    RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const { -    if (RD->hasNonTrivialCopyConstructor()) +    if (RD->hasNonTrivialCopyConstructor() || RD->hasNonTrivialDestructor())        return RAA_DirectInMemory;      return RAA_Default;    } @@ -44,42 +50,153 @@ public:    // arbitrary.    StringRef GetDeletedVirtualCallName() { return "_purecall"; } +  bool isInlineInitializedStaticDataMemberLinkOnce() { return true; } +    llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,                                        llvm::Value *ptr,                                        QualType type); +  llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF, +                                         llvm::Value *This, +                                         const CXXRecordDecl *ClassDecl, +                                         const CXXRecordDecl *BaseClassDecl); +    void BuildConstructorSignature(const CXXConstructorDecl *Ctor,                                   CXXCtorType Type,                                   CanQualType &ResTy,                                   SmallVectorImpl<CanQualType> &ArgTys); -  llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF); +  llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, +                                                  const CXXRecordDecl *RD); + +  void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF, +                                                 const CXXRecordDecl *RD); + +  void EmitCXXConstructors(const CXXConstructorDecl *D); + +  // Background on MSVC destructors +  // ============================== +  // +  // Both Itanium and MSVC ABIs have destructor variants.  The variant names +  // roughly correspond in the following way: +  //   Itanium       Microsoft +  //   Base       -> no name, just ~Class +  //   Complete   -> vbase destructor +  //   Deleting   -> scalar deleting destructor +  //                 vector deleting destructor +  // +  // The base and complete destructors are the same as in Itanium, although the +  // complete destructor does not accept a VTT parameter when there are virtual +  // bases.  A separate mechanism involving vtordisps is used to ensure that +  // virtual methods of destroyed subobjects are not called. +  // +  // The deleting destructors accept an i32 bitfield as a second parameter.  Bit +  // 1 indicates if the memory should be deleted.  Bit 2 indicates if the this +  // pointer points to an array.  The scalar deleting destructor assumes that +  // bit 2 is zero, and therefore does not contain a loop. +  // +  // For virtual destructors, only one entry is reserved in the vftable, and it +  // always points to the vector deleting destructor.  The vector deleting +  // destructor is the most general, so it can be used to destroy objects in +  // place, delete single heap objects, or delete arrays. +  // +  // A TU defining a non-inline destructor is only guaranteed to emit a base +  // destructor, and all of the other variants are emitted on an as-needed basis +  // in COMDATs.  Because a non-base destructor can be emitted in a TU that +  // lacks a definition for the destructor, non-base destructors must always +  // delegate to or alias the base destructor. -  void BuildDestructorSignature(const CXXDestructorDecl *Ctor, +  void BuildDestructorSignature(const CXXDestructorDecl *Dtor,                                  CXXDtorType Type,                                  CanQualType &ResTy,                                  SmallVectorImpl<CanQualType> &ArgTys); +  /// Non-base dtors should be emitted as delegating thunks in this ABI. +  bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, +                              CXXDtorType DT) const { +    return DT != Dtor_Base; +  } + +  void EmitCXXDestructors(const CXXDestructorDecl *D); + +  const CXXRecordDecl *getThisArgumentTypeForMethod(const CXXMethodDecl *MD) { +    MD = MD->getCanonicalDecl(); +    if (MD->isVirtual() && !isa<CXXDestructorDecl>(MD)) { +      MicrosoftVTableContext::MethodVFTableLocation ML = +          CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD); +      // The vbases might be ordered differently in the final overrider object +      // and the complete object, so the "this" argument may sometimes point to +      // memory that has no particular type (e.g. past the complete object). +      // In this case, we just use a generic pointer type. +      // FIXME: might want to have a more precise type in the non-virtual +      // multiple inheritance case. +      if (ML.VBase || !ML.VFPtrOffset.isZero()) +        return 0; +    } +    return MD->getParent(); +  } + +  llvm::Value *adjustThisArgumentForVirtualCall(CodeGenFunction &CGF, +                                                GlobalDecl GD, +                                                llvm::Value *This); +    void BuildInstanceFunctionParams(CodeGenFunction &CGF,                                     QualType &ResTy,                                     FunctionArgList &Params); +  llvm::Value *adjustThisParameterInVirtualFunctionPrologue( +      CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This); +    void EmitInstanceFunctionProlog(CodeGenFunction &CGF); -  llvm::Value *EmitConstructorCall(CodeGenFunction &CGF, -                           const CXXConstructorDecl *D, -                           CXXCtorType Type, bool ForVirtualBase, -                           bool Delegating, +  void EmitConstructorCall(CodeGenFunction &CGF, +                           const CXXConstructorDecl *D, CXXCtorType Type, +                           bool ForVirtualBase, bool Delegating,                             llvm::Value *This,                             CallExpr::const_arg_iterator ArgBeg,                             CallExpr::const_arg_iterator ArgEnd); -  RValue EmitVirtualDestructorCall(CodeGenFunction &CGF, -                                   const CXXDestructorDecl *Dtor, -                                   CXXDtorType DtorType, -                                   SourceLocation CallLoc, -                                   ReturnValueSlot ReturnValue, -                                   llvm::Value *This); +  void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD); + +  llvm::Value *getVTableAddressPointInStructor( +      CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, +      BaseSubobject Base, const CXXRecordDecl *NearestVBase, +      bool &NeedsVirtualOffset); + +  llvm::Constant * +  getVTableAddressPointForConstExpr(BaseSubobject Base, +                                    const CXXRecordDecl *VTableClass); + +  llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, +                                        CharUnits VPtrOffset); + +  llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, +                                         llvm::Value *This, llvm::Type *Ty); + +  void EmitVirtualDestructorCall(CodeGenFunction &CGF, +                                 const CXXDestructorDecl *Dtor, +                                 CXXDtorType DtorType, SourceLocation CallLoc, +                                 llvm::Value *This); + +  void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD, +                                        CallArgList &CallArgs) { +    assert(GD.getDtorType() == Dtor_Deleting && +           "Only deleting destructor thunks are available in this ABI"); +    CallArgs.add(RValue::get(getStructorImplicitParamValue(CGF)), +                             CGM.getContext().IntTy); +  } + +  void emitVirtualInheritanceTables(const CXXRecordDecl *RD); + +  void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) { +    Thunk->setLinkage(llvm::GlobalValue::WeakAnyLinkage); +  } + +  llvm::Value *performThisAdjustment(CodeGenFunction &CGF, llvm::Value *This, +                                     const ThisAdjustment &TA); + +  llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, llvm::Value *Ret, +                                       const ReturnAdjustment &RA);    void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,                         llvm::GlobalVariable *DeclPtr, @@ -119,9 +236,12 @@ public:    llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,                                     llvm::Value *allocPtr,                                     CharUnits cookieSize); -  static bool needThisReturn(GlobalDecl GD);  private: +  MicrosoftMangleContext &getMangleContext() { +    return cast<MicrosoftMangleContext>(CodeGen::CGCXXABI::getMangleContext()); +  } +    llvm::Constant *getZeroInt() {      return llvm::ConstantInt::get(CGM.IntTy, 0);    } @@ -130,10 +250,44 @@ private:      return  llvm::Constant::getAllOnesValue(CGM.IntTy);    } +  llvm::Constant *getConstantOrZeroInt(llvm::Constant *C) { +    return C ? C : getZeroInt(); +  } + +  llvm::Value *getValueOrZeroInt(llvm::Value *C) { +    return C ? C : getZeroInt(); +  } +    void    GetNullMemberPointerFields(const MemberPointerType *MPT,                               llvm::SmallVectorImpl<llvm::Constant *> &fields); +  /// \brief Finds the offset from the base of RD to the vbptr it uses, even if +  /// it is reusing a vbptr from a non-virtual base.  RD must have morally +  /// virtual bases. +  CharUnits GetVBPtrOffsetFromBases(const CXXRecordDecl *RD); + +  /// \brief Shared code for virtual base adjustment.  Returns the offset from +  /// the vbptr to the virtual base.  Optionally returns the address of the +  /// vbptr itself. +  llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, +                                       llvm::Value *Base, +                                       llvm::Value *VBPtrOffset, +                                       llvm::Value *VBTableOffset, +                                       llvm::Value **VBPtr = 0); + +  llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, +                                       llvm::Value *Base, +                                       int32_t VBPtrOffset, +                                       int32_t VBTableOffset, +                                       llvm::Value **VBPtr = 0) { +    llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset), +                *VBTOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableOffset); +    return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr); +  } + +  /// \brief Performs a full virtual base adjustment.  Used to dereference +  /// pointers to members of virtual bases.    llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const CXXRecordDecl *RD,                                   llvm::Value *Base,                                   llvm::Value *VirtualBaseAdjustmentOffset, @@ -143,7 +297,25 @@ private:    /// function member pointers.    llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,                                          bool IsMemberFunction, -                                        const CXXRecordDecl *RD); +                                        const CXXRecordDecl *RD, +                                        CharUnits NonVirtualBaseAdjustment); + +  llvm::Constant *BuildMemberPointer(const CXXRecordDecl *RD, +                                     const CXXMethodDecl *MD, +                                     CharUnits NonVirtualBaseAdjustment); + +  bool MemberPointerConstantIsNull(const MemberPointerType *MPT, +                                   llvm::Constant *MP); + +  /// \brief - Initialize all vbptrs of 'this' with RD as the complete type. +  void EmitVBPtrStores(CodeGenFunction &CGF, const CXXRecordDecl *RD); + +  /// \brief Caching wrapper around VBTableBuilder::enumerateVBTables(). +  const VBTableVector &EnumerateVBTables(const CXXRecordDecl *RD); + +  /// \brief Generate a thunk for calling a virtual member function MD. +  llvm::Function *EmitVirtualMemPtrThunk(const CXXMethodDecl *MD, +                                         StringRef ThunkName);  public:    virtual llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT); @@ -172,12 +344,43 @@ public:                                                      llvm::Value *MemPtr,                                                    const MemberPointerType *MPT); +  virtual llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF, +                                                   const CastExpr *E, +                                                   llvm::Value *Src); + +  virtual llvm::Constant *EmitMemberPointerConversion(const CastExpr *E, +                                                      llvm::Constant *Src); +    virtual llvm::Value *    EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,                                    llvm::Value *&This,                                    llvm::Value *MemPtr,                                    const MemberPointerType *MPT); +private: +  typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy; +  typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VFTablesMapTy; +  /// \brief All the vftables that have been referenced. +  VFTablesMapTy VFTablesMap; + +  /// \brief This set holds the record decls we've deferred vtable emission for. +  llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables; + + +  /// \brief All the vbtables which have been referenced. +  llvm::DenseMap<const CXXRecordDecl *, VBTableVector> VBTablesMap; + +  /// Info on the global variable used to guard initialization of static locals. +  /// The BitIndex field is only used for externally invisible declarations. +  struct GuardInfo { +    GuardInfo() : Guard(0), BitIndex(0) {} +    llvm::GlobalVariable *Guard; +    unsigned BitIndex; +  }; + +  /// Map from DeclContext to the current guard variable.  We assume that the +  /// AST is visited in source code order. +  llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;  };  } @@ -189,19 +392,65 @@ llvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,    return ptr;  } -bool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) { -  const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl()); -  return isa<CXXConstructorDecl>(MD); +/// \brief Finds the first non-virtual base of RD that has virtual bases.  If RD +/// doesn't have a vbptr, it will reuse the vbptr of the returned class. +static const CXXRecordDecl *FindFirstNVBaseWithVBases(const CXXRecordDecl *RD) { +  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), +       E = RD->bases_end(); I != E; ++I) { +    const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl(); +    if (!I->isVirtual() && Base->getNumVBases() > 0) +      return Base; +  } +  llvm_unreachable("RD must have an nv base with vbases"); +} + +CharUnits MicrosoftCXXABI::GetVBPtrOffsetFromBases(const CXXRecordDecl *RD) { +  assert(RD->getNumVBases()); +  CharUnits Total = CharUnits::Zero(); +  while (RD) { +    const ASTRecordLayout &RDLayout = getContext().getASTRecordLayout(RD); +    CharUnits VBPtrOffset = RDLayout.getVBPtrOffset(); +    // -1 is the sentinel for no vbptr. +    if (VBPtrOffset != CharUnits::fromQuantity(-1)) { +      Total += VBPtrOffset; +      break; +    } +    RD = FindFirstNVBaseWithVBases(RD); +    Total += RDLayout.getBaseClassOffset(RD); +  } +  return Total; +} + +llvm::Value * +MicrosoftCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF, +                                           llvm::Value *This, +                                           const CXXRecordDecl *ClassDecl, +                                           const CXXRecordDecl *BaseClassDecl) { +  int64_t VBPtrChars = GetVBPtrOffsetFromBases(ClassDecl).getQuantity(); +  llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars); +  CharUnits IntSize = getContext().getTypeSizeInChars(getContext().IntTy); +  CharUnits VBTableChars = +      IntSize * +      CGM.getMicrosoftVTableContext().getVBTableIndex(ClassDecl, BaseClassDecl); +  llvm::Value *VBTableOffset = +    llvm::ConstantInt::get(CGM.IntTy, VBTableChars.getQuantity()); + +  llvm::Value *VBPtrToNewBase = +    GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset); +  VBPtrToNewBase = +    CGF.Builder.CreateSExtOrBitCast(VBPtrToNewBase, CGM.PtrDiffTy); +  return CGF.Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase); +} + +bool MicrosoftCXXABI::HasThisReturn(GlobalDecl GD) const { +  return isa<CXXConstructorDecl>(GD.getDecl());  }  void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,                                   CXXCtorType Type,                                   CanQualType &ResTy,                                   SmallVectorImpl<CanQualType> &ArgTys) { -  // 'this' is already in place - -  // Ctor returns this ptr -  ResTy = ArgTys[0]; +  // 'this' parameter and 'this' return are already in place    const CXXRecordDecl *Class = Ctor->getParent();    if (Class->getNumVBases()) { @@ -210,13 +459,14 @@ void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,    }  } -llvm::BasicBlock *MicrosoftCXXABI::EmitCtorCompleteObjectHandler( -                                                         CodeGenFunction &CGF) { +llvm::BasicBlock * +MicrosoftCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, +                                               const CXXRecordDecl *RD) {    llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);    assert(IsMostDerivedClass &&           "ctor for a class with virtual bases must have an implicit parameter"); -  llvm::Value *IsCompleteObject -    = CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object"); +  llvm::Value *IsCompleteObject = +    CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object");    llvm::BasicBlock *CallVbaseCtorsBB = CGF.createBasicBlock("ctor.init_vbases");    llvm::BasicBlock *SkipVbaseCtorsBB = CGF.createBasicBlock("ctor.skip_vbases"); @@ -224,24 +474,200 @@ llvm::BasicBlock *MicrosoftCXXABI::EmitCtorCompleteObjectHandler(                             CallVbaseCtorsBB, SkipVbaseCtorsBB);    CGF.EmitBlock(CallVbaseCtorsBB); -  // FIXME: emit vbtables somewhere around here. + +  // Fill in the vbtable pointers here. +  EmitVBPtrStores(CGF, RD);    // CGF will put the base ctor calls in this basic block for us later.    return SkipVbaseCtorsBB;  } +void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers( +    CodeGenFunction &CGF, const CXXRecordDecl *RD) { +  // In most cases, an override for a vbase virtual method can adjust +  // the "this" parameter by applying a constant offset. +  // However, this is not enough while a constructor or a destructor of some +  // class X is being executed if all the following conditions are met: +  //  - X has virtual bases, (1) +  //  - X overrides a virtual method M of a vbase Y, (2) +  //  - X itself is a vbase of the most derived class. +  // +  // If (1) and (2) are true, the vtorDisp for vbase Y is a hidden member of X +  // which holds the extra amount of "this" adjustment we must do when we use +  // the X vftables (i.e. during X ctor or dtor). +  // Outside the ctors and dtors, the values of vtorDisps are zero. + +  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); +  typedef ASTRecordLayout::VBaseOffsetsMapTy VBOffsets; +  const VBOffsets &VBaseMap = Layout.getVBaseOffsetsMap(); +  CGBuilderTy &Builder = CGF.Builder; + +  unsigned AS = +      cast<llvm::PointerType>(getThisValue(CGF)->getType())->getAddressSpace(); +  llvm::Value *Int8This = 0;  // Initialize lazily. + +  for (VBOffsets::const_iterator I = VBaseMap.begin(), E = VBaseMap.end(); +        I != E; ++I) { +    if (!I->second.hasVtorDisp()) +      continue; + +    llvm::Value *VBaseOffset = +        GetVirtualBaseClassOffset(CGF, getThisValue(CGF), RD, I->first); +    // FIXME: it doesn't look right that we SExt in GetVirtualBaseClassOffset() +    // just to Trunc back immediately. +    VBaseOffset = Builder.CreateTruncOrBitCast(VBaseOffset, CGF.Int32Ty); +    uint64_t ConstantVBaseOffset = +        Layout.getVBaseClassOffset(I->first).getQuantity(); + +    // vtorDisp_for_vbase = vbptr[vbase_idx] - offsetof(RD, vbase). +    llvm::Value *VtorDispValue = Builder.CreateSub( +        VBaseOffset, llvm::ConstantInt::get(CGM.Int32Ty, ConstantVBaseOffset), +        "vtordisp.value"); + +    if (!Int8This) +      Int8This = Builder.CreateBitCast(getThisValue(CGF), +                                       CGF.Int8Ty->getPointerTo(AS)); +    llvm::Value *VtorDispPtr = Builder.CreateInBoundsGEP(Int8This, VBaseOffset); +    // vtorDisp is always the 32-bits before the vbase in the class layout. +    VtorDispPtr = Builder.CreateConstGEP1_32(VtorDispPtr, -4); +    VtorDispPtr = Builder.CreateBitCast( +        VtorDispPtr, CGF.Int32Ty->getPointerTo(AS), "vtordisp.ptr"); + +    Builder.CreateStore(VtorDispValue, VtorDispPtr); +  } +} + +void MicrosoftCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) { +  // There's only one constructor type in this ABI. +  CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete)); +} + +void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF, +                                      const CXXRecordDecl *RD) { +  llvm::Value *ThisInt8Ptr = +    CGF.Builder.CreateBitCast(getThisValue(CGF), CGM.Int8PtrTy, "this.int8"); + +  const VBTableVector &VBTables = EnumerateVBTables(RD); +  for (VBTableVector::const_iterator I = VBTables.begin(), E = VBTables.end(); +       I != E; ++I) { +    const ASTRecordLayout &SubobjectLayout = +      CGM.getContext().getASTRecordLayout(I->VBPtrSubobject.getBase()); +    uint64_t Offs = (I->VBPtrSubobject.getBaseOffset() + +                     SubobjectLayout.getVBPtrOffset()).getQuantity(); +    llvm::Value *VBPtr = +        CGF.Builder.CreateConstInBoundsGEP1_64(ThisInt8Ptr, Offs); +    VBPtr = CGF.Builder.CreateBitCast(VBPtr, I->GV->getType()->getPointerTo(0), +                                      "vbptr." + I->ReusingBase->getName()); +    CGF.Builder.CreateStore(I->GV, VBPtr); +  } +} +  void MicrosoftCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,                                                 CXXDtorType Type,                                                 CanQualType &ResTy,                                          SmallVectorImpl<CanQualType> &ArgTys) {    // 'this' is already in place +    // TODO: 'for base' flag    if (Type == Dtor_Deleting) { -    // The scalar deleting destructor takes an implicit bool parameter. -    ArgTys.push_back(CGM.getContext().BoolTy); +    // The scalar deleting destructor takes an implicit int parameter. +    ArgTys.push_back(CGM.getContext().IntTy); +  } +} + +void MicrosoftCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) { +  // The TU defining a dtor is only guaranteed to emit a base destructor.  All +  // other destructor variants are delegating thunks. +  CGM.EmitGlobal(GlobalDecl(D, Dtor_Base)); +} + +llvm::Value *MicrosoftCXXABI::adjustThisArgumentForVirtualCall( +    CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This) { +  GD = GD.getCanonicalDecl(); +  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); +  // FIXME: consider splitting the vdtor vs regular method code into two +  // functions. + +  GlobalDecl LookupGD = GD; +  if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { +    // Complete dtors take a pointer to the complete object, +    // thus don't need adjustment. +    if (GD.getDtorType() == Dtor_Complete) +      return This; + +    // There's only Dtor_Deleting in vftable but it shares the this adjustment +    // with the base one, so look up the deleting one instead. +    LookupGD = GlobalDecl(DD, Dtor_Deleting); +  } +  MicrosoftVTableContext::MethodVFTableLocation ML = +      CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD); + +  unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace(); +  llvm::Type *charPtrTy = CGF.Int8Ty->getPointerTo(AS); +  CharUnits StaticOffset = ML.VFPtrOffset; +  if (ML.VBase) { +    bool AvoidVirtualOffset = false; +    if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) { +      // A base destructor can only be called from a complete destructor of the +      // same record type or another destructor of a more derived type; +      // or a constructor of the same record type if an exception is thrown. +      assert(isa<CXXDestructorDecl>(CGF.CurGD.getDecl()) || +             isa<CXXConstructorDecl>(CGF.CurGD.getDecl())); +      const CXXRecordDecl *CurRD = +          cast<CXXMethodDecl>(CGF.CurGD.getDecl())->getParent(); + +      if (MD->getParent() == CurRD) { +        if (isa<CXXDestructorDecl>(CGF.CurGD.getDecl())) +          assert(CGF.CurGD.getDtorType() == Dtor_Complete); +        if (isa<CXXConstructorDecl>(CGF.CurGD.getDecl())) +          assert(CGF.CurGD.getCtorType() == Ctor_Complete); +        // We're calling the main base dtor from a complete structor, +        // so we know the "this" offset statically. +        AvoidVirtualOffset = true; +      } else { +        // Let's see if we try to call a destructor of a non-virtual base. +        for (CXXRecordDecl::base_class_const_iterator I = CurRD->bases_begin(), +             E = CurRD->bases_end(); I != E; ++I) { +          if (I->getType()->getAsCXXRecordDecl() != MD->getParent()) +            continue; +          // If we call a base destructor for a non-virtual base, we statically +          // know where it expects the vfptr and "this" to be. +          // The total offset should reflect the adjustment done by +          // adjustThisParameterInVirtualFunctionPrologue(). +          AvoidVirtualOffset = true; +          break; +        } +      } +    } + +    if (AvoidVirtualOffset) { +      const ASTRecordLayout &Layout = +          CGF.getContext().getASTRecordLayout(MD->getParent()); +      StaticOffset += Layout.getVBaseClassOffset(ML.VBase); +    } else { +      This = CGF.Builder.CreateBitCast(This, charPtrTy); +      llvm::Value *VBaseOffset = +          GetVirtualBaseClassOffset(CGF, This, MD->getParent(), ML.VBase); +      This = CGF.Builder.CreateInBoundsGEP(This, VBaseOffset); +    } +  } +  if (!StaticOffset.isZero()) { +    assert(StaticOffset.isPositive()); +    This = CGF.Builder.CreateBitCast(This, charPtrTy); +    if (ML.VBase) { +      // Non-virtual adjustment might result in a pointer outside the allocated +      // object, e.g. if the final overrider class is laid out after the virtual +      // base that declares a method in the most derived class. +      // FIXME: Update the code that emits this adjustment in thunks prologues. +      This = CGF.Builder.CreateConstGEP1_32(This, StaticOffset.getQuantity()); +    } else { +      This = CGF.Builder.CreateConstInBoundsGEP1_32(This, +                                                    StaticOffset.getQuantity()); +    }    } +  return This;  }  static bool IsDeletingDtor(GlobalDecl GD) { @@ -256,9 +682,6 @@ void MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,                                                    QualType &ResTy,                                                    FunctionArgList &Params) {    BuildThisParam(CGF, Params); -  if (needThisReturn(CGF.CurGD)) { -    ResTy = Params[0]->getType(); -  }    ASTContext &Context = getContext();    const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); @@ -275,17 +698,71 @@ void MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,        = ImplicitParamDecl::Create(Context, 0,                                    CGF.CurGD.getDecl()->getLocation(),                                    &Context.Idents.get("should_call_delete"), -                                  Context.BoolTy); +                                  Context.IntTy);      Params.push_back(ShouldDelete);      getStructorImplicitParamDecl(CGF) = ShouldDelete;    }  } +llvm::Value *MicrosoftCXXABI::adjustThisParameterInVirtualFunctionPrologue( +    CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This) { +  GD = GD.getCanonicalDecl(); +  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); + +  GlobalDecl LookupGD = GD; +  if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { +    // Complete destructors take a pointer to the complete object as a +    // parameter, thus don't need this adjustment. +    if (GD.getDtorType() == Dtor_Complete) +      return This; + +    // There's no Dtor_Base in vftable but it shares the this adjustment with +    // the deleting one, so look it up instead. +    LookupGD = GlobalDecl(DD, Dtor_Deleting); +  } + +  // In this ABI, every virtual function takes a pointer to one of the +  // subobjects that first defines it as the 'this' parameter, rather than a +  // pointer to ther final overrider subobject. Thus, we need to adjust it back +  // to the final overrider subobject before use. +  // See comments in the MicrosoftVFTableContext implementation for the details. + +  MicrosoftVTableContext::MethodVFTableLocation ML = +      CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD); +  CharUnits Adjustment = ML.VFPtrOffset; +  if (ML.VBase) { +    const ASTRecordLayout &DerivedLayout = +        CGF.getContext().getASTRecordLayout(MD->getParent()); +    Adjustment += DerivedLayout.getVBaseClassOffset(ML.VBase); +  } + +  if (Adjustment.isZero()) +    return This; + +  unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace(); +  llvm::Type *charPtrTy = CGF.Int8Ty->getPointerTo(AS), +             *thisTy = This->getType(); + +  This = CGF.Builder.CreateBitCast(This, charPtrTy); +  assert(Adjustment.isPositive()); +  This = +      CGF.Builder.CreateConstInBoundsGEP1_32(This, -Adjustment.getQuantity()); +  return CGF.Builder.CreateBitCast(This, thisTy); +} +  void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {    EmitThisParam(CGF); -  if (needThisReturn(CGF.CurGD)) { + +  /// If this is a function that the ABI specifies returns 'this', initialize +  /// the return slot to 'this' at the start of the function. +  /// +  /// Unlike the setting of return types, this is done within the ABI +  /// implementation instead of by clients of CGCXXABI because: +  /// 1) getThisValue is currently protected +  /// 2) in theory, an ABI could implement 'this' returns some other way; +  ///    HasThisReturn only specifies a contract, not the implementation     +  if (HasThisReturn(CGF.CurGD))      CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue); -  }    const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());    if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) { @@ -307,9 +784,10 @@ void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {    }  } -llvm::Value *MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF, +void MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF,                                            const CXXConstructorDecl *D, -                                          CXXCtorType Type, bool ForVirtualBase, +                                          CXXCtorType Type,  +                                          bool ForVirtualBase,                                            bool Delegating,                                            llvm::Value *This,                                            CallExpr::const_arg_iterator ArgBeg, @@ -326,33 +804,291 @@ llvm::Value *MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF,    // FIXME: Provide a source location here.    CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This, -                        ImplicitParam, ImplicitParamTy, -                        ArgBeg, ArgEnd); -  return Callee; +                        ImplicitParam, ImplicitParamTy, ArgBeg, ArgEnd); +} + +void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, +                                            const CXXRecordDecl *RD) { +  MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext(); +  MicrosoftVTableContext::VFPtrListTy VFPtrs = VFTContext.getVFPtrOffsets(RD); +  llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD); + +  for (MicrosoftVTableContext::VFPtrListTy::iterator I = VFPtrs.begin(), +       E = VFPtrs.end(); I != E; ++I) { +    llvm::GlobalVariable *VTable = getAddrOfVTable(RD, I->VFPtrFullOffset); +    if (VTable->hasInitializer()) +      continue; + +    const VTableLayout &VTLayout = +        VFTContext.getVFTableLayout(RD, I->VFPtrFullOffset); +    llvm::Constant *Init = CGVT.CreateVTableInitializer( +        RD, VTLayout.vtable_component_begin(), +        VTLayout.getNumVTableComponents(), VTLayout.vtable_thunk_begin(), +        VTLayout.getNumVTableThunks()); +    VTable->setInitializer(Init); + +    VTable->setLinkage(Linkage); +    CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForVTable); +  } +} + +llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor( +    CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base, +    const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) { +  NeedsVirtualOffset = (NearestVBase != 0); + +  llvm::Value *VTableAddressPoint = +      getAddrOfVTable(VTableClass, Base.getBaseOffset()); +  if (!VTableAddressPoint) { +    assert(Base.getBase()->getNumVBases() && +           !CGM.getContext().getASTRecordLayout(Base.getBase()).hasOwnVFPtr()); +  } +  return VTableAddressPoint; +} + +static void mangleVFTableName(MicrosoftMangleContext &MangleContext, +                              const CXXRecordDecl *RD, const VFPtrInfo &VFPtr, +                              SmallString<256> &Name) { +  llvm::raw_svector_ostream Out(Name); +  MangleContext.mangleCXXVFTable(RD, VFPtr.PathToMangle, Out); +} + +llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr( +    BaseSubobject Base, const CXXRecordDecl *VTableClass) { +  llvm::Constant *VTable = getAddrOfVTable(VTableClass, Base.getBaseOffset()); +  assert(VTable && "Couldn't find a vftable for the given base?"); +  return VTable; +} + +llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, +                                                       CharUnits VPtrOffset) { +  // getAddrOfVTable may return 0 if asked to get an address of a vtable which +  // shouldn't be used in the given record type. We want to cache this result in +  // VFTablesMap, thus a simple zero check is not sufficient. +  VFTableIdTy ID(RD, VPtrOffset); +  VFTablesMapTy::iterator I; +  bool Inserted; +  llvm::tie(I, Inserted) = VFTablesMap.insert( +      std::make_pair(ID, static_cast<llvm::GlobalVariable *>(0))); +  if (!Inserted) +    return I->second; + +  llvm::GlobalVariable *&VTable = I->second; + +  MicrosoftVTableContext &VTContext = CGM.getMicrosoftVTableContext(); +  const MicrosoftVTableContext::VFPtrListTy &VFPtrs = +      VTContext.getVFPtrOffsets(RD); + +  if (DeferredVFTables.insert(RD)) { +    // We haven't processed this record type before. +    // Queue up this v-table for possible deferred emission. +    CGM.addDeferredVTable(RD); + +#ifndef NDEBUG +    // Create all the vftables at once in order to make sure each vftable has +    // a unique mangled name. +    llvm::StringSet<> ObservedMangledNames; +    for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) { +      SmallString<256> Name; +      mangleVFTableName(getMangleContext(), RD, VFPtrs[J], Name); +      if (!ObservedMangledNames.insert(Name.str())) +        llvm_unreachable("Already saw this mangling before?"); +    } +#endif +  } + +  for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) { +    if (VFPtrs[J].VFPtrFullOffset != VPtrOffset) +      continue; + +    llvm::ArrayType *ArrayType = llvm::ArrayType::get( +        CGM.Int8PtrTy, +        VTContext.getVFTableLayout(RD, VFPtrs[J].VFPtrFullOffset) +            .getNumVTableComponents()); + +    SmallString<256> Name; +    mangleVFTableName(getMangleContext(), RD, VFPtrs[J], Name); +    VTable = CGM.CreateOrReplaceCXXRuntimeVariable( +        Name.str(), ArrayType, llvm::GlobalValue::ExternalLinkage); +    VTable->setUnnamedAddr(true); +    break; +  } + +  return VTable;  } -RValue MicrosoftCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF, -                                                  const CXXDestructorDecl *Dtor, -                                                  CXXDtorType DtorType, -                                                  SourceLocation CallLoc, -                                                  ReturnValueSlot ReturnValue, -                                                  llvm::Value *This) { +llvm::Value *MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, +                                                        GlobalDecl GD, +                                                        llvm::Value *This, +                                                        llvm::Type *Ty) { +  GD = GD.getCanonicalDecl(); +  CGBuilderTy &Builder = CGF.Builder; + +  Ty = Ty->getPointerTo()->getPointerTo(); +  llvm::Value *VPtr = adjustThisArgumentForVirtualCall(CGF, GD, This); +  llvm::Value *VTable = CGF.GetVTablePtr(VPtr, Ty); + +  MicrosoftVTableContext::MethodVFTableLocation ML = +      CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD); +  llvm::Value *VFuncPtr = +      Builder.CreateConstInBoundsGEP1_64(VTable, ML.Index, "vfn"); +  return Builder.CreateLoad(VFuncPtr); +} + +void MicrosoftCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF, +                                                const CXXDestructorDecl *Dtor, +                                                CXXDtorType DtorType, +                                                SourceLocation CallLoc, +                                                llvm::Value *This) {    assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);    // We have only one destructor in the vftable but can get both behaviors -  // by passing an implicit bool parameter. -  const CGFunctionInfo *FInfo -      = &CGM.getTypes().arrangeCXXDestructor(Dtor, Dtor_Deleting); +  // by passing an implicit int parameter. +  GlobalDecl GD(Dtor, Dtor_Deleting); +  const CGFunctionInfo *FInfo = +      &CGM.getTypes().arrangeCXXDestructor(Dtor, Dtor_Deleting);    llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); -  llvm::Value *Callee = CGF.BuildVirtualCall(Dtor, Dtor_Deleting, This, Ty); +  llvm::Value *Callee = getVirtualFunctionPointer(CGF, GD, This, Ty);    ASTContext &Context = CGF.getContext(); -  llvm::Value *ImplicitParam -    = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(CGF.getLLVMContext()), +  llvm::Value *ImplicitParam = +      llvm::ConstantInt::get(llvm::IntegerType::getInt32Ty(CGF.getLLVMContext()),                               DtorType == Dtor_Deleting); -  return CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValue, This, -                               ImplicitParam, Context.BoolTy, 0, 0); +  This = adjustThisArgumentForVirtualCall(CGF, GD, This); +  CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValueSlot(), This, +                        ImplicitParam, Context.IntTy, 0, 0); +} + +const VBTableVector & +MicrosoftCXXABI::EnumerateVBTables(const CXXRecordDecl *RD) { +  // At this layer, we can key the cache off of a single class, which is much +  // easier than caching at the GlobalVariable layer. +  llvm::DenseMap<const CXXRecordDecl*, VBTableVector>::iterator I; +  bool added; +  llvm::tie(I, added) = VBTablesMap.insert(std::make_pair(RD, VBTableVector())); +  VBTableVector &VBTables = I->second; +  if (!added) +    return VBTables; + +  VBTableBuilder(CGM, RD).enumerateVBTables(VBTables); + +  return VBTables; +} + +llvm::Function * +MicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD, +                                        StringRef ThunkName) { +  // If the thunk has been generated previously, just return it. +  if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName)) +    return cast<llvm::Function>(GV); + +  // Create the llvm::Function. +  const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeGlobalDeclaration(MD); +  llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo); +  llvm::Function *ThunkFn = +      llvm::Function::Create(ThunkTy, llvm::Function::ExternalLinkage, +                             ThunkName.str(), &CGM.getModule()); +  assert(ThunkFn->getName() == ThunkName && "name was uniqued!"); + +  ThunkFn->setLinkage(MD->isExternallyVisible() +                          ? llvm::GlobalValue::LinkOnceODRLinkage +                          : llvm::GlobalValue::InternalLinkage); + +  CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn); +  CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn); + +  // Start codegen. +  CodeGenFunction CGF(CGM); +  CGF.StartThunk(ThunkFn, MD, FnInfo); + +  // Get to the Callee. +  llvm::Value *This = CGF.LoadCXXThis(); +  llvm::Value *Callee = getVirtualFunctionPointer(CGF, MD, This, ThunkTy); + +  // Make the call and return the result. +  CGF.EmitCallAndReturnForThunk(MD, Callee, 0); + +  return ThunkFn; +} + +void MicrosoftCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) { +  const VBTableVector &VBTables = EnumerateVBTables(RD); +  llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD); + +  for (VBTableVector::const_iterator I = VBTables.begin(), E = VBTables.end(); +       I != E; ++I) { +    I->EmitVBTableDefinition(CGM, RD, Linkage); +  } +} + +llvm::Value *MicrosoftCXXABI::performThisAdjustment(CodeGenFunction &CGF, +                                                    llvm::Value *This, +                                                    const ThisAdjustment &TA) { +  if (TA.isEmpty()) +    return This; + +  llvm::Value *V = CGF.Builder.CreateBitCast(This, CGF.Int8PtrTy); + +  if (!TA.Virtual.isEmpty()) { +    assert(TA.Virtual.Microsoft.VtordispOffset < 0); +    // Adjust the this argument based on the vtordisp value. +    llvm::Value *VtorDispPtr = +        CGF.Builder.CreateConstGEP1_32(V, TA.Virtual.Microsoft.VtordispOffset); +    VtorDispPtr = +        CGF.Builder.CreateBitCast(VtorDispPtr, CGF.Int32Ty->getPointerTo()); +    llvm::Value *VtorDisp = CGF.Builder.CreateLoad(VtorDispPtr, "vtordisp"); +    V = CGF.Builder.CreateGEP(V, CGF.Builder.CreateNeg(VtorDisp)); + +    if (TA.Virtual.Microsoft.VBPtrOffset) { +      // If the final overrider is defined in a virtual base other than the one +      // that holds the vfptr, we have to use a vtordispex thunk which looks up +      // the vbtable of the derived class. +      assert(TA.Virtual.Microsoft.VBPtrOffset > 0); +      assert(TA.Virtual.Microsoft.VBOffsetOffset >= 0); +      llvm::Value *VBPtr; +      llvm::Value *VBaseOffset = +          GetVBaseOffsetFromVBPtr(CGF, V, -TA.Virtual.Microsoft.VBPtrOffset, +                                  TA.Virtual.Microsoft.VBOffsetOffset, &VBPtr); +      V = CGF.Builder.CreateInBoundsGEP(VBPtr, VBaseOffset); +    } +  } + +  if (TA.NonVirtual) { +    // Non-virtual adjustment might result in a pointer outside the allocated +    // object, e.g. if the final overrider class is laid out after the virtual +    // base that declares a method in the most derived class. +    V = CGF.Builder.CreateConstGEP1_32(V, TA.NonVirtual); +  } + +  // Don't need to bitcast back, the call CodeGen will handle this. +  return V; +} + +llvm::Value * +MicrosoftCXXABI::performReturnAdjustment(CodeGenFunction &CGF, llvm::Value *Ret, +                                         const ReturnAdjustment &RA) { +  if (RA.isEmpty()) +    return Ret; + +  llvm::Value *V = CGF.Builder.CreateBitCast(Ret, CGF.Int8PtrTy); + +  if (RA.Virtual.Microsoft.VBIndex) { +    assert(RA.Virtual.Microsoft.VBIndex > 0); +    int32_t IntSize = +        getContext().getTypeSizeInChars(getContext().IntTy).getQuantity(); +    llvm::Value *VBPtr; +    llvm::Value *VBaseOffset = +        GetVBaseOffsetFromVBPtr(CGF, V, RA.Virtual.Microsoft.VBPtrOffset, +                                IntSize * RA.Virtual.Microsoft.VBIndex, &VBPtr); +    V = CGF.Builder.CreateInBoundsGEP(VBPtr, VBaseOffset); +  } + +  if (RA.NonVirtual) +    V = CGF.Builder.CreateConstInBoundsGEP1_32(V, RA.NonVirtual); + +  // Cast back to the original type. +  return CGF.Builder.CreateBitCast(V, Ret->getType());  }  bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr, @@ -411,17 +1147,86 @@ llvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,  }  void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, -                                      llvm::GlobalVariable *DeclPtr, +                                      llvm::GlobalVariable *GV,                                        bool PerformInit) { -  // FIXME: this code was only tested for global initialization. -  // Not sure whether we want thread-safe static local variables as VS -  // doesn't make them thread-safe. +  // MSVC always uses an i32 bitfield to guard initialization, which is *not* +  // threadsafe.  Since the user may be linking in inline functions compiled by +  // cl.exe, there's no reason to provide a false sense of security by using +  // critical sections here.    if (D.getTLSKind())      CGM.ErrorUnsupported(&D, "dynamic TLS initialization"); -  // Emit the initializer and add a global destructor if appropriate. -  CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit); +  CGBuilderTy &Builder = CGF.Builder; +  llvm::IntegerType *GuardTy = CGF.Int32Ty; +  llvm::ConstantInt *Zero = llvm::ConstantInt::get(GuardTy, 0); + +  // Get the guard variable for this function if we have one already. +  GuardInfo &GI = GuardVariableMap[D.getDeclContext()]; + +  unsigned BitIndex; +  if (D.isExternallyVisible()) { +    // Externally visible variables have to be numbered in Sema to properly +    // handle unreachable VarDecls. +    BitIndex = getContext().getManglingNumber(&D); +    assert(BitIndex > 0); +    BitIndex--; +  } else { +    // Non-externally visible variables are numbered here in CodeGen. +    BitIndex = GI.BitIndex++; +  } + +  if (BitIndex >= 32) { +    if (D.isExternallyVisible()) +      ErrorUnsupportedABI(CGF, "more than 32 guarded initializations"); +    BitIndex %= 32; +    GI.Guard = 0; +  } + +  // Lazily create the i32 bitfield for this function. +  if (!GI.Guard) { +    // Mangle the name for the guard. +    SmallString<256> GuardName; +    { +      llvm::raw_svector_ostream Out(GuardName); +      getMangleContext().mangleStaticGuardVariable(&D, Out); +      Out.flush(); +    } + +    // Create the guard variable with a zero-initializer.  Just absorb linkage +    // and visibility from the guarded variable. +    GI.Guard = new llvm::GlobalVariable(CGM.getModule(), GuardTy, false, +                                     GV->getLinkage(), Zero, GuardName.str()); +    GI.Guard->setVisibility(GV->getVisibility()); +  } else { +    assert(GI.Guard->getLinkage() == GV->getLinkage() && +           "static local from the same function had different linkage"); +  } + +  // Pseudo code for the test: +  // if (!(GuardVar & MyGuardBit)) { +  //   GuardVar |= MyGuardBit; +  //   ... initialize the object ...; +  // } + +  // Test our bit from the guard variable. +  llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1U << BitIndex); +  llvm::LoadInst *LI = Builder.CreateLoad(GI.Guard); +  llvm::Value *IsInitialized = +      Builder.CreateICmpNE(Builder.CreateAnd(LI, Bit), Zero); +  llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init"); +  llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end"); +  Builder.CreateCondBr(IsInitialized, EndBlock, InitBlock); + +  // Set our bit in the guard variable and emit the initializer and add a global +  // destructor if appropriate. +  CGF.EmitBlock(InitBlock); +  Builder.CreateStore(Builder.CreateOr(LI, Bit), GI.Guard); +  CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit); +  Builder.CreateBr(EndBlock); + +  // Continue. +  CGF.EmitBlock(EndBlock);  }  // Member pointer helpers. @@ -429,8 +1234,10 @@ static bool hasVBPtrOffsetField(MSInheritanceModel Inheritance) {    return Inheritance == MSIM_Unspecified;  } -static bool hasOnlyOneField(MSInheritanceModel Inheritance) { -  return Inheritance <= MSIM_SinglePolymorphic; +static bool hasOnlyOneField(bool IsMemberFunction, +                            MSInheritanceModel Inheritance) { +  return Inheritance <= MSIM_SinglePolymorphic || +      (!IsMemberFunction && Inheritance <= MSIM_MultiplePolymorphic);  }  // Only member pointers to functions need a this adjustment, since it can be @@ -531,27 +1338,28 @@ MicrosoftCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {  llvm::Constant *  MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,                                         bool IsMemberFunction, -                                       const CXXRecordDecl *RD) +                                       const CXXRecordDecl *RD, +                                       CharUnits NonVirtualBaseAdjustment)  {    MSInheritanceModel Inheritance = RD->getMSInheritanceModel();    // Single inheritance class member pointer are represented as scalars instead    // of aggregates. -  if (hasOnlyOneField(Inheritance)) +  if (hasOnlyOneField(IsMemberFunction, Inheritance))      return FirstField;    llvm::SmallVector<llvm::Constant *, 4> fields;    fields.push_back(FirstField);    if (hasNonVirtualBaseAdjustmentField(IsMemberFunction, Inheritance)) -    fields.push_back(getZeroInt()); +    fields.push_back(llvm::ConstantInt::get( +      CGM.IntTy, NonVirtualBaseAdjustment.getQuantity()));    if (hasVBPtrOffsetField(Inheritance)) { -    int64_t VBPtrOffset = -      getContext().getASTRecordLayout(RD).getVBPtrOffset().getQuantity(); -    if (VBPtrOffset == -1) -      VBPtrOffset = 0; -    fields.push_back(llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset)); +    CharUnits Offs = CharUnits::Zero(); +    if (RD->getNumVBases()) +      Offs = GetVBPtrOffsetFromBases(RD); +    fields.push_back(llvm::ConstantInt::get(CGM.IntTy, Offs.getQuantity()));    }    // The rest of the fields are adjusted by conversions to a more derived class. @@ -567,22 +1375,44 @@ MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,    const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();    llvm::Constant *FirstField =      llvm::ConstantInt::get(CGM.IntTy, offset.getQuantity()); -  return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/false, RD); +  return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/false, RD, +                               CharUnits::Zero()); +} + +llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { +  return BuildMemberPointer(MD->getParent(), MD, CharUnits::Zero()); +} + +llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const APValue &MP, +                                                   QualType MPType) { +  const MemberPointerType *MPT = MPType->castAs<MemberPointerType>(); +  const ValueDecl *MPD = MP.getMemberPointerDecl(); +  if (!MPD) +    return EmitNullMemberPointer(MPT); + +  CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP); + +  // FIXME PR15713: Support virtual inheritance paths. + +  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) +    return BuildMemberPointer(MPT->getClass()->getAsCXXRecordDecl(), +                              MD, ThisAdjustment); + +  CharUnits FieldOffset = +    getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD)); +  return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);  }  llvm::Constant * -MicrosoftCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { +MicrosoftCXXABI::BuildMemberPointer(const CXXRecordDecl *RD, +                                    const CXXMethodDecl *MD, +                                    CharUnits NonVirtualBaseAdjustment) {    assert(MD->isInstance() && "Member function must not be static!");    MD = MD->getCanonicalDecl(); -  const CXXRecordDecl *RD = MD->getParent();    CodeGenTypes &Types = CGM.getTypes();    llvm::Constant *FirstField; -  if (MD->isVirtual()) { -    // FIXME: We have to instantiate a thunk that loads the vftable and jumps to -    // the right offset. -    FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy); -  } else { +  if (!MD->isVirtual()) {      const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();      llvm::Type *Ty;      // Check whether the function has a computable LLVM signature. @@ -596,18 +1426,38 @@ MicrosoftCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {      }      FirstField = CGM.GetAddrOfFunction(MD, Ty);      FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.VoidPtrTy); +  } else { +    MicrosoftVTableContext::MethodVFTableLocation ML = +        CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD); +    if (MD->isVariadic()) { +      CGM.ErrorUnsupported(MD, "pointer to variadic virtual member function"); +      FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy); +    } else if (!CGM.getTypes().isFuncTypeConvertible( +                    MD->getType()->castAs<FunctionType>())) { +      CGM.ErrorUnsupported(MD, "pointer to virtual member function with " +                               "incomplete return or parameter type"); +      FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy); +    } else if (ML.VBase) { +      CGM.ErrorUnsupported(MD, "pointer to virtual member function overriding " +                               "member function in virtual base class"); +      FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy); +    } else { +      SmallString<256> ThunkName; +      CharUnits PointerWidth = getContext().toCharUnitsFromBits( +          getContext().getTargetInfo().getPointerWidth(0)); +      uint64_t OffsetInVFTable = ML.Index * PointerWidth.getQuantity(); +      llvm::raw_svector_ostream Out(ThunkName); +      getMangleContext().mangleVirtualMemPtrThunk(MD, OffsetInVFTable, Out); +      Out.flush(); + +      llvm::Function *Thunk = EmitVirtualMemPtrThunk(MD, ThunkName.str()); +      FirstField = llvm::ConstantExpr::getBitCast(Thunk, CGM.VoidPtrTy); +    }    }    // The rest of the fields are common with data member pointers. -  return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/true, RD); -} - -llvm::Constant * -MicrosoftCXXABI::EmitMemberPointer(const APValue &MP, QualType MPT) { -  // FIXME PR15875: Implement member pointer conversions for Constants. -  const CXXRecordDecl *RD = MPT->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl(); -  return EmitFullMemberPointer(llvm::Constant::getNullValue(CGM.VoidPtrTy), -                               /*IsMemberFunction=*/true, RD); +  return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/true, RD, +                               NonVirtualBaseAdjustment);  }  /// Member pointers are the same if they're either bitwise identical *or* both @@ -638,7 +1488,7 @@ MicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,    // single icmp.    const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();    MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); -  if (hasOnlyOneField(Inheritance)) +  if (hasOnlyOneField(MPT->isMemberFunctionPointer(), Inheritance))      return Builder.CreateICmp(Eq, L, R);    // Compare the first field. @@ -703,12 +1553,64 @@ MicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,    return Res;  } +bool MicrosoftCXXABI::MemberPointerConstantIsNull(const MemberPointerType *MPT, +                                                  llvm::Constant *Val) { +  // Function pointers are null if the pointer in the first field is null. +  if (MPT->isMemberFunctionPointer()) { +    llvm::Constant *FirstField = Val->getType()->isStructTy() ? +      Val->getAggregateElement(0U) : Val; +    return FirstField->isNullValue(); +  } + +  // If it's not a function pointer and it's zero initializable, we can easily +  // check zero. +  if (isZeroInitializable(MPT) && Val->isNullValue()) +    return true; + +  // Otherwise, break down all the fields for comparison.  Hopefully these +  // little Constants are reused, while a big null struct might not be. +  llvm::SmallVector<llvm::Constant *, 4> Fields; +  GetNullMemberPointerFields(MPT, Fields); +  if (Fields.size() == 1) { +    assert(Val->getType()->isIntegerTy()); +    return Val == Fields[0]; +  } + +  unsigned I, E; +  for (I = 0, E = Fields.size(); I != E; ++I) { +    if (Val->getAggregateElement(I) != Fields[I]) +      break; +  } +  return I == E; +} + +llvm::Value * +MicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, +                                         llvm::Value *This, +                                         llvm::Value *VBPtrOffset, +                                         llvm::Value *VBTableOffset, +                                         llvm::Value **VBPtrOut) { +  CGBuilderTy &Builder = CGF.Builder; +  // Load the vbtable pointer from the vbptr in the instance. +  This = Builder.CreateBitCast(This, CGM.Int8PtrTy); +  llvm::Value *VBPtr = +    Builder.CreateInBoundsGEP(This, VBPtrOffset, "vbptr"); +  if (VBPtrOut) *VBPtrOut = VBPtr; +  VBPtr = Builder.CreateBitCast(VBPtr, CGM.Int8PtrTy->getPointerTo(0)); +  llvm::Value *VBTable = Builder.CreateLoad(VBPtr, "vbtable"); + +  // Load an i32 offset from the vb-table. +  llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableOffset); +  VBaseOffs = Builder.CreateBitCast(VBaseOffs, CGM.Int32Ty->getPointerTo(0)); +  return Builder.CreateLoad(VBaseOffs, "vbase_offs"); +} +  // Returns an adjusted base cast to i8*, since we do more address arithmetic on  // it.  llvm::Value *  MicrosoftCXXABI::AdjustVirtualBase(CodeGenFunction &CGF,                                     const CXXRecordDecl *RD, llvm::Value *Base, -                                   llvm::Value *VirtualBaseAdjustmentOffset, +                                   llvm::Value *VBTableOffset,                                     llvm::Value *VBPtrOffset) {    CGBuilderTy &Builder = CGF.Builder;    Base = Builder.CreateBitCast(Base, CGM.Int8PtrTy); @@ -725,7 +1627,7 @@ MicrosoftCXXABI::AdjustVirtualBase(CodeGenFunction &CGF,      VBaseAdjustBB = CGF.createBasicBlock("memptr.vadjust");      SkipAdjustBB = CGF.createBasicBlock("memptr.skip_vadjust");      llvm::Value *IsVirtual = -      Builder.CreateICmpNE(VirtualBaseAdjustmentOffset, getZeroInt(), +      Builder.CreateICmpNE(VBTableOffset, getZeroInt(),                             "memptr.is_vbase");      Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);      CGF.EmitBlock(VBaseAdjustBB); @@ -734,21 +1636,15 @@ MicrosoftCXXABI::AdjustVirtualBase(CodeGenFunction &CGF,    // If we weren't given a dynamic vbptr offset, RD should be complete and we'll    // know the vbptr offset.    if (!VBPtrOffset) { -    CharUnits offs = getContext().getASTRecordLayout(RD).getVBPtrOffset(); +    CharUnits offs = CharUnits::Zero(); +    if (RD->getNumVBases()) { +      offs = GetVBPtrOffsetFromBases(RD); +    }      VBPtrOffset = llvm::ConstantInt::get(CGM.IntTy, offs.getQuantity());    } -  // Load the vbtable pointer from the vbtable offset in the instance. -  llvm::Value *VBPtr = -    Builder.CreateInBoundsGEP(Base, VBPtrOffset, "memptr.vbptr"); -  llvm::Value *VBTable = -    Builder.CreateBitCast(VBPtr, CGM.Int8PtrTy->getPointerTo(0)); -  VBTable = Builder.CreateLoad(VBTable, "memptr.vbtable"); -  // Load an i32 offset from the vb-table. +  llvm::Value *VBPtr = 0;    llvm::Value *VBaseOffs = -    Builder.CreateInBoundsGEP(VBTable, VirtualBaseAdjustmentOffset); -  VBaseOffs = Builder.CreateBitCast(VBaseOffs, CGM.Int32Ty->getPointerTo(0)); -  VBaseOffs = Builder.CreateLoad(VBaseOffs, "memptr.vbase_offs"); -  // Add it to VBPtr.  GEP will sign extend the i32 value for us. +    GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);    llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs);    // Merge control flow with the case where we didn't have to adjust. @@ -803,6 +1699,194 @@ MicrosoftCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,    return Builder.CreateBitCast(Addr, PType);  } +static MSInheritanceModel +getInheritanceFromMemptr(const MemberPointerType *MPT) { +  return MPT->getClass()->getAsCXXRecordDecl()->getMSInheritanceModel(); +} + +llvm::Value * +MicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, +                                             const CastExpr *E, +                                             llvm::Value *Src) { +  assert(E->getCastKind() == CK_DerivedToBaseMemberPointer || +         E->getCastKind() == CK_BaseToDerivedMemberPointer || +         E->getCastKind() == CK_ReinterpretMemberPointer); + +  // Use constant emission if we can. +  if (isa<llvm::Constant>(Src)) +    return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src)); + +  // We may be adding or dropping fields from the member pointer, so we need +  // both types and the inheritance models of both records. +  const MemberPointerType *SrcTy = +    E->getSubExpr()->getType()->castAs<MemberPointerType>(); +  const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>(); +  MSInheritanceModel SrcInheritance = getInheritanceFromMemptr(SrcTy); +  MSInheritanceModel DstInheritance = getInheritanceFromMemptr(DstTy); +  bool IsFunc = SrcTy->isMemberFunctionPointer(); + +  // If the classes use the same null representation, reinterpret_cast is a nop. +  bool IsReinterpret = E->getCastKind() == CK_ReinterpretMemberPointer; +  if (IsReinterpret && (IsFunc || +                        nullFieldOffsetIsZero(SrcInheritance) == +                        nullFieldOffsetIsZero(DstInheritance))) +    return Src; + +  CGBuilderTy &Builder = CGF.Builder; + +  // Branch past the conversion if Src is null. +  llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy); +  llvm::Constant *DstNull = EmitNullMemberPointer(DstTy); + +  // C++ 5.2.10p9: The null member pointer value is converted to the null member +  //   pointer value of the destination type. +  if (IsReinterpret) { +    // For reinterpret casts, sema ensures that src and dst are both functions +    // or data and have the same size, which means the LLVM types should match. +    assert(Src->getType() == DstNull->getType()); +    return Builder.CreateSelect(IsNotNull, Src, DstNull); +  } + +  llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock(); +  llvm::BasicBlock *ConvertBB = CGF.createBasicBlock("memptr.convert"); +  llvm::BasicBlock *ContinueBB = CGF.createBasicBlock("memptr.converted"); +  Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB); +  CGF.EmitBlock(ConvertBB); + +  // Decompose src. +  llvm::Value *FirstField = Src; +  llvm::Value *NonVirtualBaseAdjustment = 0; +  llvm::Value *VirtualBaseAdjustmentOffset = 0; +  llvm::Value *VBPtrOffset = 0; +  if (!hasOnlyOneField(IsFunc, SrcInheritance)) { +    // We need to extract values. +    unsigned I = 0; +    FirstField = Builder.CreateExtractValue(Src, I++); +    if (hasNonVirtualBaseAdjustmentField(IsFunc, SrcInheritance)) +      NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++); +    if (hasVBPtrOffsetField(SrcInheritance)) +      VBPtrOffset = Builder.CreateExtractValue(Src, I++); +    if (hasVirtualBaseAdjustmentField(SrcInheritance)) +      VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++); +  } + +  // For data pointers, we adjust the field offset directly.  For functions, we +  // have a separate field. +  llvm::Constant *Adj = getMemberPointerAdjustment(E); +  if (Adj) { +    Adj = llvm::ConstantExpr::getTruncOrBitCast(Adj, CGM.IntTy); +    llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField; +    bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); +    if (!NVAdjustField)  // If this field didn't exist in src, it's zero. +      NVAdjustField = getZeroInt(); +    if (isDerivedToBase) +      NVAdjustField = Builder.CreateNSWSub(NVAdjustField, Adj, "adj"); +    else +      NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, Adj, "adj"); +  } + +  // FIXME PR15713: Support conversions through virtually derived classes. + +  // Recompose dst from the null struct and the adjusted fields from src. +  llvm::Value *Dst; +  if (hasOnlyOneField(IsFunc, DstInheritance)) { +    Dst = FirstField; +  } else { +    Dst = llvm::UndefValue::get(DstNull->getType()); +    unsigned Idx = 0; +    Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++); +    if (hasNonVirtualBaseAdjustmentField(IsFunc, DstInheritance)) +      Dst = Builder.CreateInsertValue( +        Dst, getValueOrZeroInt(NonVirtualBaseAdjustment), Idx++); +    if (hasVBPtrOffsetField(DstInheritance)) +      Dst = Builder.CreateInsertValue( +        Dst, getValueOrZeroInt(VBPtrOffset), Idx++); +    if (hasVirtualBaseAdjustmentField(DstInheritance)) +      Dst = Builder.CreateInsertValue( +        Dst, getValueOrZeroInt(VirtualBaseAdjustmentOffset), Idx++); +  } +  Builder.CreateBr(ContinueBB); + +  // In the continuation, choose between DstNull and Dst. +  CGF.EmitBlock(ContinueBB); +  llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2, "memptr.converted"); +  Phi->addIncoming(DstNull, OriginalBB); +  Phi->addIncoming(Dst, ConvertBB); +  return Phi; +} + +llvm::Constant * +MicrosoftCXXABI::EmitMemberPointerConversion(const CastExpr *E, +                                             llvm::Constant *Src) { +  const MemberPointerType *SrcTy = +    E->getSubExpr()->getType()->castAs<MemberPointerType>(); +  const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>(); + +  // If src is null, emit a new null for dst.  We can't return src because dst +  // might have a new representation. +  if (MemberPointerConstantIsNull(SrcTy, Src)) +    return EmitNullMemberPointer(DstTy); + +  // We don't need to do anything for reinterpret_casts of non-null member +  // pointers.  We should only get here when the two type representations have +  // the same size. +  if (E->getCastKind() == CK_ReinterpretMemberPointer) +    return Src; + +  MSInheritanceModel SrcInheritance = getInheritanceFromMemptr(SrcTy); +  MSInheritanceModel DstInheritance = getInheritanceFromMemptr(DstTy); + +  // Decompose src. +  llvm::Constant *FirstField = Src; +  llvm::Constant *NonVirtualBaseAdjustment = 0; +  llvm::Constant *VirtualBaseAdjustmentOffset = 0; +  llvm::Constant *VBPtrOffset = 0; +  bool IsFunc = SrcTy->isMemberFunctionPointer(); +  if (!hasOnlyOneField(IsFunc, SrcInheritance)) { +    // We need to extract values. +    unsigned I = 0; +    FirstField = Src->getAggregateElement(I++); +    if (hasNonVirtualBaseAdjustmentField(IsFunc, SrcInheritance)) +      NonVirtualBaseAdjustment = Src->getAggregateElement(I++); +    if (hasVBPtrOffsetField(SrcInheritance)) +      VBPtrOffset = Src->getAggregateElement(I++); +    if (hasVirtualBaseAdjustmentField(SrcInheritance)) +      VirtualBaseAdjustmentOffset = Src->getAggregateElement(I++); +  } + +  // For data pointers, we adjust the field offset directly.  For functions, we +  // have a separate field. +  llvm::Constant *Adj = getMemberPointerAdjustment(E); +  if (Adj) { +    Adj = llvm::ConstantExpr::getTruncOrBitCast(Adj, CGM.IntTy); +    llvm::Constant *&NVAdjustField = +      IsFunc ? NonVirtualBaseAdjustment : FirstField; +    bool IsDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); +    if (!NVAdjustField)  // If this field didn't exist in src, it's zero. +      NVAdjustField = getZeroInt(); +    if (IsDerivedToBase) +      NVAdjustField = llvm::ConstantExpr::getNSWSub(NVAdjustField, Adj); +    else +      NVAdjustField = llvm::ConstantExpr::getNSWAdd(NVAdjustField, Adj); +  } + +  // FIXME PR15713: Support conversions through virtually derived classes. + +  // Recompose dst from the null struct and the adjusted fields from src. +  if (hasOnlyOneField(IsFunc, DstInheritance)) +    return FirstField; + +  llvm::SmallVector<llvm::Constant *, 4> Fields; +  Fields.push_back(FirstField); +  if (hasNonVirtualBaseAdjustmentField(IsFunc, DstInheritance)) +    Fields.push_back(getConstantOrZeroInt(NonVirtualBaseAdjustment)); +  if (hasVBPtrOffsetField(DstInheritance)) +    Fields.push_back(getConstantOrZeroInt(VBPtrOffset)); +  if (hasVirtualBaseAdjustmentField(DstInheritance)) +    Fields.push_back(getConstantOrZeroInt(VirtualBaseAdjustmentOffset)); +  return llvm::ConstantStruct::getAnon(Fields); +} +  llvm::Value *  MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,                                                   llvm::Value *&This, @@ -855,4 +1939,3 @@ MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,  CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {    return new MicrosoftCXXABI(CGM);  } - diff --git a/lib/CodeGen/MicrosoftVBTables.cpp b/lib/CodeGen/MicrosoftVBTables.cpp new file mode 100644 index 0000000000000..dabf52c1ccc1a --- /dev/null +++ b/lib/CodeGen/MicrosoftVBTables.cpp @@ -0,0 +1,233 @@ +//===--- MicrosoftVBTables.cpp - Virtual Base Table Emission --------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class generates data about MSVC virtual base tables. +// +//===----------------------------------------------------------------------===// + +#include "MicrosoftVBTables.h" +#include "CodeGenModule.h" +#include "CGCXXABI.h" + +namespace clang { +namespace CodeGen { + +/// Holds intermediate data about a path to a vbptr inside a base subobject. +struct VBTablePath { +  VBTablePath(const VBTableInfo &VBInfo) +    : VBInfo(VBInfo), NextBase(VBInfo.VBPtrSubobject.getBase()) { } + +  /// All the data needed to build a vbtable, minus the GlobalVariable whose +  /// name we haven't computed yet. +  VBTableInfo VBInfo; + +  /// Next base to use for disambiguation.  Can be null if we've already +  /// disambiguated this path once. +  const CXXRecordDecl *NextBase; + +  /// Path is not really a full path like a CXXBasePath.  It holds the subset of +  /// records that need to be mangled into the vbtable symbol name in order to get +  /// a unique name. +  llvm::SmallVector<const CXXRecordDecl *, 1> Path; +}; + +VBTableBuilder::VBTableBuilder(CodeGenModule &CGM, +                               const CXXRecordDecl *MostDerived) +    : CGM(CGM), MostDerived(MostDerived), +      DerivedLayout(CGM.getContext().getASTRecordLayout(MostDerived)) {} + +void VBTableBuilder::enumerateVBTables(VBTableVector &VBTables) { +  VBTablePathVector Paths; +  findUnambiguousPaths(MostDerived, BaseSubobject(MostDerived, +                                                  CharUnits::Zero()), Paths); +  for (VBTablePathVector::iterator I = Paths.begin(), E = Paths.end(); +       I != E; ++I) { +    VBTablePath *P = *I; +    P->VBInfo.GV = getAddrOfVBTable(P->VBInfo.ReusingBase, P->Path); +    VBTables.push_back(P->VBInfo); +  } +} + + +void VBTableBuilder::findUnambiguousPaths(const CXXRecordDecl *ReusingBase, +                                          BaseSubobject CurSubobject, +                                          VBTablePathVector &Paths) { +  size_t PathsStart = Paths.size(); +  bool ReuseVBPtrFromBase = true; +  const CXXRecordDecl *CurBase = CurSubobject.getBase(); +  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(CurBase); + +  // If this base has a vbptr, then we've found a path.  These are not full +  // paths, so we don't use CXXBasePath. +  if (Layout.hasOwnVBPtr()) { +    ReuseVBPtrFromBase = false; +    VBTablePath *Info = new VBTablePath( +      VBTableInfo(ReusingBase, CurSubobject, /*GV=*/0)); +    Paths.push_back(Info); +  } + +  // Recurse onto any bases which themselves have virtual bases. +  for (CXXRecordDecl::base_class_const_iterator I = CurBase->bases_begin(), +       E = CurBase->bases_end(); I != E; ++I) { +    const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl(); +    if (!Base->getNumVBases()) +      continue;  // Bases without virtual bases have no vbptrs. +    CharUnits NextOffset; +    const CXXRecordDecl *NextReusingBase = Base; +    if (I->isVirtual()) { +      if (!VBasesSeen.insert(Base)) +        continue;  // Don't visit virtual bases twice. +      NextOffset = DerivedLayout.getVBaseClassOffset(Base); +    } else { +      NextOffset = (CurSubobject.getBaseOffset() + +                    Layout.getBaseClassOffset(Base)); + +      // If CurBase didn't have a vbptr, then ReusingBase will reuse the vbptr +      // from the first non-virtual base with vbases for its vbptr. +      if (ReuseVBPtrFromBase) { +        NextReusingBase = ReusingBase; +        ReuseVBPtrFromBase = false; +      } +    } + +    size_t NumPaths = Paths.size(); +    findUnambiguousPaths(NextReusingBase, BaseSubobject(Base, NextOffset), +                         Paths); + +    // Tag paths through this base with the base itself.  We might use it to +    // disambiguate. +    for (size_t I = NumPaths, E = Paths.size(); I != E; ++I) +      Paths[I]->NextBase = Base; +  } + +  bool AmbiguousPaths = rebucketPaths(Paths, PathsStart); +  if (AmbiguousPaths) +    rebucketPaths(Paths, PathsStart, /*SecondPass=*/true); + +#ifndef NDEBUG +  // Check that the paths are in fact unique. +  for (size_t I = PathsStart + 1, E = Paths.size(); I != E; ++I) { +    assert(Paths[I]->Path != Paths[I - 1]->Path && "vbtable paths are not unique"); +  } +#endif +} + +static bool pathCompare(VBTablePath *LHS, VBTablePath *RHS) { +  return LHS->Path < RHS->Path; +} + +void VBTableBuilder::extendPath(VBTablePath *P, bool SecondPass) { +  assert(P->NextBase || SecondPass); +  if (P->NextBase) { +    P->Path.push_back(P->NextBase); +    P->NextBase = 0;  // Prevent the path from being extended twice. +  } +} + +bool VBTableBuilder::rebucketPaths(VBTablePathVector &Paths, size_t PathsStart, +                                   bool SecondPass) { +  // What we're essentially doing here is bucketing together ambiguous paths. +  // Any bucket with more than one path in it gets extended by NextBase, which +  // is usually the direct base of the inherited the vbptr.  This code uses a +  // sorted vector to implement a multiset to form the buckets.  Note that the +  // ordering is based on pointers, but it doesn't change our output order.  The +  // current algorithm is designed to match MSVC 2012's names. +  // TODO: Implement MSVC 2010 or earlier names to avoid extra vbtable cruft. +  VBTablePathVector PathsSorted(&Paths[PathsStart], &Paths.back() + 1); +  std::sort(PathsSorted.begin(), PathsSorted.end(), pathCompare); +  bool AmbiguousPaths = false; +  for (size_t I = 0, E = PathsSorted.size(); I != E;) { +    // Scan forward to find the end of the bucket. +    size_t BucketStart = I; +    do { +      ++I; +    } while (I != E && PathsSorted[BucketStart]->Path == PathsSorted[I]->Path); + +    // If this bucket has multiple paths, extend them all. +    if (I - BucketStart > 1) { +      AmbiguousPaths = true; +      for (size_t II = BucketStart; II != I; ++II) +        extendPath(PathsSorted[II], SecondPass); +    } +  } +  return AmbiguousPaths; +} + +llvm::GlobalVariable * +VBTableBuilder::getAddrOfVBTable(const CXXRecordDecl *ReusingBase, +                                 ArrayRef<const CXXRecordDecl *> BasePath) { +  // Caching at this layer is redundant with the caching in EnumerateVBTables(). + +  SmallString<256> OutName; +  llvm::raw_svector_ostream Out(OutName); +  MicrosoftMangleContext &Mangler = +      cast<MicrosoftMangleContext>(CGM.getCXXABI().getMangleContext()); +  Mangler.mangleCXXVBTable(MostDerived, BasePath, Out); +  Out.flush(); +  StringRef Name = OutName.str(); + +  llvm::ArrayType *VBTableType = +    llvm::ArrayType::get(CGM.IntTy, 1 + ReusingBase->getNumVBases()); + +  assert(!CGM.getModule().getNamedGlobal(Name) && +         "vbtable with this name already exists: mangling bug?"); +  llvm::GlobalVariable *VBTable = +    CGM.CreateOrReplaceCXXRuntimeVariable(Name, VBTableType, +                                          llvm::GlobalValue::ExternalLinkage); +  VBTable->setUnnamedAddr(true); +  return VBTable; +} + +void VBTableInfo::EmitVBTableDefinition( +    CodeGenModule &CGM, const CXXRecordDecl *RD, +    llvm::GlobalVariable::LinkageTypes Linkage) const { +  assert(RD->getNumVBases() && ReusingBase->getNumVBases() && +         "should only emit vbtables for classes with vbtables"); + +  const ASTRecordLayout &BaseLayout = +    CGM.getContext().getASTRecordLayout(VBPtrSubobject.getBase()); +  const ASTRecordLayout &DerivedLayout = +    CGM.getContext().getASTRecordLayout(RD); + +  SmallVector<llvm::Constant *, 4> Offsets(1 + ReusingBase->getNumVBases(), 0); + +  // The offset from ReusingBase's vbptr to itself always leads. +  CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset(); +  Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity()); + +  MicrosoftVTableContext &Context = CGM.getMicrosoftVTableContext(); +  for (CXXRecordDecl::base_class_const_iterator I = ReusingBase->vbases_begin(), +       E = ReusingBase->vbases_end(); I != E; ++I) { +    const CXXRecordDecl *VBase = I->getType()->getAsCXXRecordDecl(); +    CharUnits Offset = DerivedLayout.getVBaseClassOffset(VBase); +    assert(!Offset.isNegative()); +    // Make it relative to the subobject vbptr. +    Offset -= VBPtrSubobject.getBaseOffset() + VBPtrOffset; +    unsigned VBIndex = Context.getVBTableIndex(ReusingBase, VBase); +    assert(Offsets[VBIndex] == 0 && "The same vbindex seen twice?"); +    Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy, Offset.getQuantity()); +  } + +  assert(Offsets.size() == +         cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType()) +                               ->getElementType())->getNumElements()); +  llvm::ArrayType *VBTableType = +    llvm::ArrayType::get(CGM.IntTy, Offsets.size()); +  llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets); +  GV->setInitializer(Init); + +  // Set the correct linkage. +  GV->setLinkage(Linkage); + +  // Set the right visibility. +  CGM.setTypeVisibility(GV, RD, CodeGenModule::TVK_ForVTable); +} + +} // namespace CodeGen +} // namespace clang diff --git a/lib/CodeGen/MicrosoftVBTables.h b/lib/CodeGen/MicrosoftVBTables.h new file mode 100644 index 0000000000000..4ad8e07582efd --- /dev/null +++ b/lib/CodeGen/MicrosoftVBTables.h @@ -0,0 +1,129 @@ +//===--- MicrosoftVBTables.h - Virtual Base Table Emission ----------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class generates data about MSVC virtual base tables. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/BaseSubobject.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/IR/GlobalVariable.h" +#include <vector> + +namespace clang { + +class ASTRecordLayout; + +namespace CodeGen { + +class CodeGenModule; + +struct VBTableInfo { +  VBTableInfo(const CXXRecordDecl *ReusingBase, BaseSubobject VBPtrSubobject, +              llvm::GlobalVariable *GV) +    : ReusingBase(ReusingBase), VBPtrSubobject(VBPtrSubobject), GV(GV) { } + +  /// The vbtable will hold all of the virtual bases of ReusingBase.  This may +  /// or may not be the same class as VBPtrSubobject.Base.  A derived class will +  /// reuse the vbptr of the first non-virtual base subobject that has one. +  const CXXRecordDecl *ReusingBase; + +  /// The vbptr is stored inside this subobject. +  BaseSubobject VBPtrSubobject; + +  /// The GlobalVariable for this vbtable. +  llvm::GlobalVariable *GV; + +  /// \brief Emits a definition for GV by setting it's initializer. +  void EmitVBTableDefinition(CodeGenModule &CGM, const CXXRecordDecl *RD, +                             llvm::GlobalVariable::LinkageTypes Linkage) const; +}; + +// These are embedded in a DenseMap and the elements are large, so we don't want +// SmallVector. +typedef std::vector<VBTableInfo> VBTableVector; + +struct VBTablePath; + +typedef llvm::SmallVector<VBTablePath *, 6> VBTablePathVector; + +/// Produces MSVC-compatible vbtable data.  The symbols produced by this builder +/// match those produced by MSVC 2012, which is different from MSVC 2010. +/// +/// Unlike Itanium, which uses only one vtable per class, MSVC uses a different +/// symbol for every "address point" installed in base subobjects.  As a result, +/// we have to compute unique symbols for every table.  Since there can be +/// multiple non-virtual base subobjects of the same class, combining the most +/// derived class with the base containing the vtable is insufficient.  The most +/// trivial algorithm would be to mangle in the entire path from base to most +/// derived, but that would be too easy and would create unnecessarily large +/// symbols.  ;) +/// +/// MSVC 2012 appears to minimize the vbtable names using the following +/// algorithm.  First, walk the class hierarchy in the usual order, depth first, +/// left to right, to find all of the subobjects which contain a vbptr field. +/// Visiting each class node yields a list of inheritance paths to vbptrs.  Each +/// record with a vbptr creates an initially empty path. +/// +/// To combine paths from child nodes, the paths are compared to check for +/// ambiguity.  Paths are "ambiguous" if multiple paths have the same set of +/// components in the same order.  Each group of ambiguous paths is extended by +/// appending the class of the base from which it came.  If the current class +/// node produced an ambiguous path, its path is extended with the current class. +/// After extending paths, MSVC again checks for ambiguity, and extends any +/// ambiguous path which wasn't already extended.  Because each node yields an +/// unambiguous set of paths, MSVC doesn't need to extend any path more than once +/// to produce an unambiguous set of paths. +/// +/// The VBTableBuilder class attempts to implement this algorithm by repeatedly +/// bucketing paths together by sorting them. +/// +/// TODO: Presumably vftables use the same algorithm. +/// +/// TODO: Implement the MSVC 2010 name mangling scheme to avoid emitting +/// duplicate vbtables with different symbols. +class VBTableBuilder { +public: +  VBTableBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerived); + +  void enumerateVBTables(VBTableVector &VBTables); + +private: +  bool hasVBPtr(const CXXRecordDecl *RD); + +  llvm::GlobalVariable *getAddrOfVBTable(const CXXRecordDecl *ReusingBase, +                                      ArrayRef<const CXXRecordDecl *> BasePath); + +  /// Enumerates paths to bases with vbptrs.  The paths elements are compressed +  /// to contain only the classes necessary to form an unambiguous path. +  void findUnambiguousPaths(const CXXRecordDecl *ReusingBase, +                            BaseSubobject CurSubobject, +                            VBTablePathVector &Paths); + +  void extendPath(VBTablePath *Info, bool SecondPass); + +  bool rebucketPaths(VBTablePathVector &Paths, size_t PathsStart, +                     bool SecondPass = false); + +  CodeGenModule &CGM; + +  const CXXRecordDecl *MostDerived; + +  /// Caches the layout of the most derived class. +  const ASTRecordLayout &DerivedLayout; + +  /// Set of vbases to avoid re-visiting the same vbases. +  llvm::SmallPtrSet<const CXXRecordDecl*, 4> VBasesSeen; +}; + +} // namespace CodeGen + +} // namespace clang diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp index 69e5b323045cd..bc7acbc39cab0 100644 --- a/lib/CodeGen/ModuleBuilder.cpp +++ b/lib/CodeGen/ModuleBuilder.cpp @@ -13,6 +13,7 @@  #include "clang/CodeGen/ModuleBuilder.h"  #include "CodeGenModule.h" +#include "CGDebugInfo.h"  #include "clang/AST/ASTContext.h"  #include "clang/AST/DeclObjC.h"  #include "clang/AST/Expr.h" @@ -20,6 +21,7 @@  #include "clang/Basic/TargetInfo.h"  #include "clang/Frontend/CodeGenOptions.h"  #include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/StringRef.h"  #include "llvm/IR/DataLayout.h"  #include "llvm/IR/LLVMContext.h"  #include "llvm/IR/Module.h" @@ -58,13 +60,22 @@ namespace {        TD.reset(new llvm::DataLayout(Ctx->getTargetInfo().getTargetDescription()));        Builder.reset(new CodeGen::CodeGenModule(Context, CodeGenOpts, *M, *TD,                                                 Diags)); + +      for (size_t i = 0, e = CodeGenOpts.DependentLibraries.size(); i < e; ++i) +        HandleDependentLibrary(CodeGenOpts.DependentLibraries[i]);      }      virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { +      if (Diags.hasErrorOccurred()) +        return; +        Builder->HandleCXXStaticMemberVarInstantiation(VD);      }      virtual bool HandleTopLevelDecl(DeclGroupRef DG) { +      if (Diags.hasErrorOccurred()) +        return true; +        // Make sure to emit all elements of a Decl.        for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)          Builder->EmitTopLevelDecl(*I); @@ -76,6 +87,9 @@ namespace {      /// client hack on the type, which can occur at any point in the file      /// (because these can be defined in declspecs).      virtual void HandleTagDeclDefinition(TagDecl *D) { +      if (Diags.hasErrorOccurred()) +        return; +        Builder->UpdateCompletedType(D);        // In C++, we may have member functions that need to be emitted at this  @@ -92,6 +106,15 @@ namespace {        }      } +    virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) LLVM_OVERRIDE { +      if (Diags.hasErrorOccurred()) +        return; + +      if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo()) +        if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) +          DI->completeRequiredType(RD); +    } +      virtual void HandleTranslationUnit(ASTContext &Ctx) {        if (Diags.hasErrorOccurred()) {          M.reset(); @@ -115,6 +138,19 @@ namespace {        Builder->EmitVTable(RD, DefinitionRequired);      } + +    virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) { +      Builder->AppendLinkerOptions(Opts); +    } + +    virtual void HandleDetectMismatch(llvm::StringRef Name, +                                      llvm::StringRef Value) { +      Builder->AddDetectMismatch(Name, Value); +    } + +    virtual void HandleDependentLibrary(llvm::StringRef Lib) { +      Builder->AddDependentLib(Lib); +    }    };  } diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 32b27b3172a6a..76acf871da26f 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -17,6 +17,7 @@  #include "CGCXXABI.h"  #include "CodeGenFunction.h"  #include "clang/AST/RecordLayout.h" +#include "clang/CodeGen/CGFunctionInfo.h"  #include "clang/Frontend/CodeGenOptions.h"  #include "llvm/ADT/Triple.h"  #include "llvm/IR/DataLayout.h" @@ -44,35 +45,40 @@ static bool isAggregateTypeForABI(QualType T) {  ABIInfo::~ABIInfo() {} -static bool isRecordReturnIndirect(const RecordType *RT, CodeGen::CodeGenTypes &CGT) { +static bool isRecordReturnIndirect(const RecordType *RT, +                                   CGCXXABI &CXXABI) {    const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());    if (!RD)      return false; -  return CGT.CGM.getCXXABI().isReturnTypeIndirect(RD); +  return CXXABI.isReturnTypeIndirect(RD);  } -static bool isRecordReturnIndirect(QualType T, CodeGen::CodeGenTypes &CGT) { +static bool isRecordReturnIndirect(QualType T, CGCXXABI &CXXABI) {    const RecordType *RT = T->getAs<RecordType>();    if (!RT)      return false; -  return isRecordReturnIndirect(RT, CGT); +  return isRecordReturnIndirect(RT, CXXABI);  }  static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, -                                              CodeGen::CodeGenTypes &CGT) { +                                              CGCXXABI &CXXABI) {    const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());    if (!RD)      return CGCXXABI::RAA_Default; -  return CGT.CGM.getCXXABI().getRecordArgABI(RD); +  return CXXABI.getRecordArgABI(RD);  }  static CGCXXABI::RecordArgABI getRecordArgABI(QualType T, -                                              CodeGen::CodeGenTypes &CGT) { +                                              CGCXXABI &CXXABI) {    const RecordType *RT = T->getAs<RecordType>();    if (!RT)      return CGCXXABI::RAA_Default; -  return getRecordArgABI(RT, CGT); +  return getRecordArgABI(RT, CXXABI); +} + +CGCXXABI &ABIInfo::getCXXABI() const { +  return CGT.getCXXABI();  }  ASTContext &ABIInfo::getContext() const { @@ -143,6 +149,16 @@ bool TargetCodeGenInfo::isNoProtoCallVariadic(const CallArgList &args,    return false;  } +void +TargetCodeGenInfo::getDependentLibraryOption(llvm::StringRef Lib, +                                             llvm::SmallString<24> &Opt) const { +  // This assumes the user is passing a library name like "rt" instead of a +  // filename like "librt.a/so", and that they don't care whether it's static or +  // dynamic. +  Opt = "-l"; +  Opt += Lib; +} +  static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays);  /// isEmptyField - Return true iff a the field is "empty", that is it @@ -381,7 +397,7 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const {    if (isAggregateTypeForABI(Ty)) {      // Records with non trivial destructors/constructors should not be passed      // by value. -    if (isRecordReturnIndirect(Ty, CGT)) +    if (isRecordReturnIndirect(Ty, getCXXABI()))        return ABIArgInfo::getIndirect(0, /*ByVal=*/false);      return ABIArgInfo::getIndirect(0); @@ -451,7 +467,7 @@ llvm::Value *PNaClABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,  /// \brief Classify argument of given type \p Ty.  ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty) const {    if (isAggregateTypeForABI(Ty)) { -    if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) +    if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))        return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);      return ABIArgInfo::getIndirect(0);    } else if (const EnumType *EnumTy = Ty->getAs<EnumType>()) { @@ -493,8 +509,16 @@ bool IsX86_MMXType(llvm::Type *IRType) {  static llvm::Type* X86AdjustInlineAsmType(CodeGen::CodeGenFunction &CGF,                                            StringRef Constraint,                                            llvm::Type* Ty) { -  if ((Constraint == "y" || Constraint == "&y") && Ty->isVectorTy()) +  if ((Constraint == "y" || Constraint == "&y") && Ty->isVectorTy()) { +    if (cast<llvm::VectorType>(Ty)->getBitWidth() != 64) { +      // Invalid MMX constraint +      return 0; +    } +      return llvm::Type::getX86_MMXTy(CGF.getLLVMContext()); +  } + +  // No operation needed    return Ty;  } @@ -557,6 +581,9 @@ public:        bool d, bool p, bool w, unsigned r)      :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p, w, r)) {} +  static bool isStructReturnInRegABI( +      const llvm::Triple &Triple, const CodeGenOptions &Opts); +    void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,                             CodeGen::CodeGenModule &CGM) const; @@ -575,6 +602,14 @@ public:      return X86AdjustInlineAsmType(CGF, Constraint, Ty);    } +  llvm::Constant *getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const { +    unsigned Sig = (0xeb << 0) |  // jmp rel8 +                   (0x06 << 8) |  //           .+0x08 +                   ('F' << 16) | +                   ('T' << 24); +    return llvm::ConstantInt::get(CGM.Int32Ty, Sig); +  } +  };  } @@ -674,7 +709,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,    if (isAggregateTypeForABI(RetTy)) {      if (const RecordType *RT = RetTy->getAs<RecordType>()) { -      if (isRecordReturnIndirect(RT, CGT)) +      if (isRecordReturnIndirect(RT, getCXXABI()))          return ABIArgInfo::getIndirect(0, /*ByVal=*/false);        // Structures with flexible arrays are always indirect. @@ -859,7 +894,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,        if (IsWin32StructABI)          return getIndirectResult(Ty, true, FreeRegs); -      if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, CGT)) +      if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI()))          return getIndirectResult(Ty, RAA == CGCXXABI::RAA_DirectInMemory, FreeRegs);        // Structures with flexible arrays are always indirect. @@ -876,9 +911,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,      bool NeedsPadding;      if (shouldUseInReg(Ty, FreeRegs, IsFastCall, NeedsPadding)) {        unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32; -      SmallVector<llvm::Type*, 3> Elements; -      for (unsigned I = 0; I < SizeInRegs; ++I) -        Elements.push_back(Int32); +      SmallVector<llvm::Type*, 3> Elements(SizeInRegs, Int32);        llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements);        return ABIArgInfo::getDirectInReg(Result);      } @@ -1110,6 +1143,9 @@ class X86_64ABIInfo : public ABIInfo {    /// containing object.  Some parameters are classified different    /// depending on whether they straddle an eightbyte boundary.    /// +  /// \param isNamedArg - Whether the argument in question is a "named" +  /// argument, as used in AMD64-ABI 3.5.7. +  ///    /// If a word is unused its result will be NoClass; if a type should    /// be passed in Memory then at least the classification of \arg Lo    /// will be Memory. @@ -1118,7 +1154,8 @@ class X86_64ABIInfo : public ABIInfo {    ///    /// If the \arg Lo class is ComplexX87, then the \arg Hi class will    /// also be ComplexX87. -  void classify(QualType T, uint64_t OffsetBase, Class &Lo, Class &Hi) const; +  void classify(QualType T, uint64_t OffsetBase, Class &Lo, Class &Hi, +                bool isNamedArg) const;    llvm::Type *GetByteVectorType(QualType Ty) const;    llvm::Type *GetSSETypeAtOffset(llvm::Type *IRType, @@ -1144,7 +1181,8 @@ class X86_64ABIInfo : public ABIInfo {    ABIArgInfo classifyArgumentType(QualType Ty,                                    unsigned freeIntRegs,                                    unsigned &neededInt, -                                  unsigned &neededSSE) const; +                                  unsigned &neededSSE, +                                  bool isNamedArg) const;    bool IsIllegalVectorType(QualType Ty) const; @@ -1171,7 +1209,8 @@ public:    bool isPassedUsingAVXType(QualType type) const {      unsigned neededInt, neededSSE;      // The freeIntRegs argument doesn't matter here. -    ABIArgInfo info = classifyArgumentType(type, 0, neededInt, neededSSE); +    ABIArgInfo info = classifyArgumentType(type, 0, neededInt, neededSSE, +                                           /*isNamedArg*/true);      if (info.isDirect()) {        llvm::Type *ty = info.getCoerceToType();        if (llvm::VectorType *vectorTy = dyn_cast_or_null<llvm::VectorType>(ty)) @@ -1237,7 +1276,7 @@ public:      // that when AVX types are involved: the ABI explicitly states it is      // undefined, and it doesn't work in practice because of how the ABI      // defines varargs anyway. -    if (fnType->getCallConv() == CC_Default || fnType->getCallConv() == CC_C) { +    if (fnType->getCallConv() == CC_C) {        bool HasAVXType = false;        for (CallArgList::const_iterator               it = args.begin(), ie = args.end(); it != ie; ++it) { @@ -1254,6 +1293,42 @@ public:      return TargetCodeGenInfo::isNoProtoCallVariadic(args, fnType);    } +  llvm::Constant *getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const { +    unsigned Sig = (0xeb << 0) |  // jmp rel8 +                   (0x0a << 8) |  //           .+0x0c +                   ('F' << 16) | +                   ('T' << 24); +    return llvm::ConstantInt::get(CGM.Int32Ty, Sig); +  } + +}; + +static std::string qualifyWindowsLibrary(llvm::StringRef Lib) { +  // If the argument does not end in .lib, automatically add the suffix. This +  // matches the behavior of MSVC. +  std::string ArgStr = Lib; +  if (!Lib.endswith_lower(".lib")) +    ArgStr += ".lib"; +  return ArgStr; +} + +class WinX86_32TargetCodeGenInfo : public X86_32TargetCodeGenInfo { +public: +  WinX86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, +        bool d, bool p, bool w, unsigned RegParms) +    : X86_32TargetCodeGenInfo(CGT, d, p, w, RegParms) {} + +  void getDependentLibraryOption(llvm::StringRef Lib, +                                 llvm::SmallString<24> &Opt) const { +    Opt = "/DEFAULTLIB:"; +    Opt += qualifyWindowsLibrary(Lib); +  } + +  void getDetectMismatchOption(llvm::StringRef Name, +                               llvm::StringRef Value, +                               llvm::SmallString<32> &Opt) const { +    Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\""; +  }  };  class WinX86_64TargetCodeGenInfo : public TargetCodeGenInfo { @@ -1274,6 +1349,18 @@ public:      AssignToArrayRange(CGF.Builder, Address, Eight8, 0, 16);      return false;    } + +  void getDependentLibraryOption(llvm::StringRef Lib, +                                 llvm::SmallString<24> &Opt) const { +    Opt = "/DEFAULTLIB:"; +    Opt += qualifyWindowsLibrary(Lib); +  } + +  void getDetectMismatchOption(llvm::StringRef Name, +                               llvm::StringRef Value, +                               llvm::SmallString<32> &Opt) const { +    Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\""; +  }  };  } @@ -1352,7 +1439,7 @@ X86_64ABIInfo::Class X86_64ABIInfo::merge(Class Accum, Class Field) {  }  void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, -                             Class &Lo, Class &Hi) const { +                             Class &Lo, Class &Hi, bool isNamedArg) const {    // FIXME: This code can be simplified by introducing a simple value class for    // Class pairs with appropriate constructor methods for the various    // situations. @@ -1378,7 +1465,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,        Current = Integer;      } else if ((k == BuiltinType::Float || k == BuiltinType::Double) ||                 (k == BuiltinType::LongDouble && -                getTarget().getTriple().getOS() == llvm::Triple::NaCl)) { +                getTarget().getTriple().isOSNaCl())) {        Current = SSE;      } else if (k == BuiltinType::LongDouble) {        Lo = X87; @@ -1391,7 +1478,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,    if (const EnumType *ET = Ty->getAs<EnumType>()) {      // Classify the underlying integer type. -    classify(ET->getDecl()->getIntegerType(), OffsetBase, Lo, Hi); +    classify(ET->getDecl()->getIntegerType(), OffsetBase, Lo, Hi, isNamedArg);      return;    } @@ -1439,7 +1526,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,        // split.        if (OffsetBase && OffsetBase != 64)          Hi = Lo; -    } else if (Size == 128 || (HasAVX && Size == 256)) { +    } else if (Size == 128 || (HasAVX && isNamedArg && Size == 256)) {        // Arguments of 256-bits are split into four eightbyte chunks. The        // least significant one belongs to class SSE and all the others to class        // SSEUP. The original Lo and Hi design considers that types can't be @@ -1447,6 +1534,10 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,        // This design isn't correct for 256-bits, but since there're no cases        // where the upper parts would need to be inspected, avoid adding        // complexity and just consider Hi to match the 64-256 part. +      // +      // Note that per 3.5.7 of AMD64-ABI, 256-bit args are only passed in +      // registers if they are "named", i.e. not part of the "..." of a +      // variadic function.        Lo = SSE;        Hi = SSEUp;      } @@ -1466,7 +1557,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,        Current = SSE;      else if (ET == getContext().DoubleTy ||               (ET == getContext().LongDoubleTy && -              getTarget().getTriple().getOS() == llvm::Triple::NaCl)) +              getTarget().getTriple().isOSNaCl()))        Lo = Hi = SSE;      else if (ET == getContext().LongDoubleTy)        Current = ComplexX87; @@ -1512,7 +1603,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,      for (uint64_t i=0, Offset=OffsetBase; i<ArraySize; ++i, Offset += EltSize) {        Class FieldLo, FieldHi; -      classify(AT->getElementType(), Offset, FieldLo, FieldHi); +      classify(AT->getElementType(), Offset, FieldLo, FieldHi, isNamedArg);        Lo = merge(Lo, FieldLo);        Hi = merge(Hi, FieldHi);        if (Lo == Memory || Hi == Memory) @@ -1535,7 +1626,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,      // AMD64-ABI 3.2.3p2: Rule 2. If a C++ object has either a non-trivial      // copy constructor or a non-trivial destructor, it is passed by invisible      // reference. -    if (getRecordArgABI(RT, CGT)) +    if (getRecordArgABI(RT, getCXXABI()))        return;      const RecordDecl *RD = RT->getDecl(); @@ -1566,7 +1657,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,          Class FieldLo, FieldHi;          uint64_t Offset =            OffsetBase + getContext().toBits(Layout.getBaseClassOffset(Base)); -        classify(i->getType(), Offset, FieldLo, FieldHi); +        classify(i->getType(), Offset, FieldLo, FieldHi, isNamedArg);          Lo = merge(Lo, FieldLo);          Hi = merge(Hi, FieldHi);          if (Lo == Memory || Hi == Memory) @@ -1619,7 +1710,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,          uint64_t EB_Lo = Offset / 64;          uint64_t EB_Hi = (Offset + Size - 1) / 64; -        FieldLo = FieldHi = NoClass; +          if (EB_Lo) {            assert(EB_Hi == EB_Lo && "Invalid classification, type > 16 bytes.");            FieldLo = NoClass; @@ -1629,7 +1720,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,            FieldHi = EB_Hi ? Integer : NoClass;          }        } else -        classify(i->getType(), Offset, FieldLo, FieldHi); +        classify(i->getType(), Offset, FieldLo, FieldHi, isNamedArg);        Lo = merge(Lo, FieldLo);        Hi = merge(Hi, FieldHi);        if (Lo == Memory || Hi == Memory) @@ -1685,7 +1776,7 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,              ABIArgInfo::getExtend() : ABIArgInfo::getDirect());    } -  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) +  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))      return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);    // Compute the byval alignment. We specify the alignment of the byval in all @@ -2017,7 +2108,7 @@ classifyReturnType(QualType RetTy) const {    // AMD64-ABI 3.2.3p4: Rule 1. Classify the return type with the    // classification algorithm.    X86_64ABIInfo::Class Lo, Hi; -  classify(RetTy, 0, Lo, Hi); +  classify(RetTy, 0, Lo, Hi, /*isNamedArg*/ true);    // Check some invariants.    assert((Hi != Memory || Lo == Memory) && "Invalid memory classification."); @@ -2142,11 +2233,12 @@ classifyReturnType(QualType RetTy) const {  }  ABIArgInfo X86_64ABIInfo::classifyArgumentType( -  QualType Ty, unsigned freeIntRegs, unsigned &neededInt, unsigned &neededSSE) +  QualType Ty, unsigned freeIntRegs, unsigned &neededInt, unsigned &neededSSE, +  bool isNamedArg)    const  {    X86_64ABIInfo::Class Lo, Hi; -  classify(Ty, 0, Lo, Hi); +  classify(Ty, 0, Lo, Hi, isNamedArg);    // Check some invariants.    // FIXME: Enforce these by construction. @@ -2174,7 +2266,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(      // COMPLEX_X87, it is passed in memory.    case X87:    case ComplexX87: -    if (getRecordArgABI(Ty, CGT) == CGCXXABI::RAA_Indirect) +    if (getRecordArgABI(Ty, getCXXABI()) == CGCXXABI::RAA_Indirect)        ++neededInt;      return getIndirectResult(Ty, freeIntRegs); @@ -2279,13 +2371,23 @@ void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {    if (FI.getReturnInfo().isIndirect())      --freeIntRegs; +  bool isVariadic = FI.isVariadic(); +  unsigned numRequiredArgs = 0; +  if (isVariadic) +    numRequiredArgs = FI.getRequiredArgs().getNumRequiredArgs(); +    // AMD64-ABI 3.2.3p3: Once arguments are classified, the registers    // get assigned (in left-to-right order) for passing as follows...    for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();         it != ie; ++it) { +    bool isNamedArg = true; +    if (isVariadic) +      isNamedArg = (it - FI.arg_begin()) <  +                    static_cast<signed>(numRequiredArgs); +      unsigned neededInt, neededSSE;      it->info = classifyArgumentType(it->type, freeIntRegs, neededInt, -                                    neededSSE); +                                    neededSSE, isNamedArg);      // AMD64-ABI 3.2.3p3: If there are no registers available for any      // eightbyte of an argument, the whole argument is passed on the @@ -2361,7 +2463,8 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,    unsigned neededInt, neededSSE;    Ty = CGF.getContext().getCanonicalType(Ty); -  ABIArgInfo AI = classifyArgumentType(Ty, 0, neededInt, neededSSE); +  ABIArgInfo AI = classifyArgumentType(Ty, 0, neededInt, neededSSE,  +                                       /*isNamedArg*/false);    // AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed    // in the registers. If not go to step 7. @@ -2425,7 +2528,8 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,      // FIXME: Cleanup.      assert(AI.isDirect() && "Unexpected ABI info for mixed regs");      llvm::StructType *ST = cast<llvm::StructType>(AI.getCoerceToType()); -    llvm::Value *Tmp = CGF.CreateTempAlloca(ST); +    llvm::Value *Tmp = CGF.CreateMemTemp(Ty); +    Tmp = CGF.Builder.CreateBitCast(Tmp, ST->getPointerTo());      assert(ST->getNumElements() == 2 && "Unexpected ABI info for mixed regs");      llvm::Type *TyLo = ST->getElementType(0);      llvm::Type *TyHi = ST->getElementType(1); @@ -2449,6 +2553,17 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,      RegAddr = CGF.Builder.CreateGEP(RegAddr, gp_offset);      RegAddr = CGF.Builder.CreateBitCast(RegAddr,                                          llvm::PointerType::getUnqual(LTy)); + +    // Copy to a temporary if necessary to ensure the appropriate alignment. +    std::pair<CharUnits, CharUnits> SizeAlign = +        CGF.getContext().getTypeInfoInChars(Ty); +    uint64_t TySize = SizeAlign.first.getQuantity(); +    unsigned TyAlign = SizeAlign.second.getQuantity(); +    if (TyAlign > 8) { +      llvm::Value *Tmp = CGF.CreateMemTemp(Ty); +      CGF.Builder.CreateMemCpy(Tmp, RegAddr, TySize, 8, false); +      RegAddr = Tmp; +    }    } else if (neededSSE == 1) {      RegAddr = CGF.Builder.CreateGEP(RegAddr, fp_offset);      RegAddr = CGF.Builder.CreateBitCast(RegAddr, @@ -2462,9 +2577,9 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,      llvm::Type *DoubleTy = CGF.DoubleTy;      llvm::Type *DblPtrTy =        llvm::PointerType::getUnqual(DoubleTy); -    llvm::StructType *ST = llvm::StructType::get(DoubleTy, -                                                       DoubleTy, NULL); -    llvm::Value *V, *Tmp = CGF.CreateTempAlloca(ST); +    llvm::StructType *ST = llvm::StructType::get(DoubleTy, DoubleTy, NULL); +    llvm::Value *V, *Tmp = CGF.CreateMemTemp(Ty); +    Tmp = CGF.Builder.CreateBitCast(Tmp, ST->getPointerTo());      V = CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegAddrLo,                                                           DblPtrTy));      CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 0)); @@ -2517,10 +2632,10 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, bool IsReturnType) const {    if (const RecordType *RT = Ty->getAs<RecordType>()) {      if (IsReturnType) { -      if (isRecordReturnIndirect(RT, CGT)) +      if (isRecordReturnIndirect(RT, getCXXABI()))          return ABIArgInfo::getIndirect(0, false);      } else { -      if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, CGT)) +      if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI()))          return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);      } @@ -2702,11 +2817,11 @@ public:           it != ie; ++it) {        // We rely on the default argument classification for the most part.        // One exception:  An aggregate containing a single floating-point -      // item must be passed in a register if one is available. +      // or vector item must be passed in a register if one is available.        const Type *T = isSingleElementStruct(it->type, getContext());        if (T) {          const BuiltinType *BT = T->getAs<BuiltinType>(); -        if (BT && BT->isFloatingPoint()) { +        if (T->isVectorType() || (BT && BT->isFloatingPoint())) {            QualType QT(T, 0);            it->info = ABIArgInfo::getDirectInReg(CGT.ConvertType(QT));            continue; @@ -2782,7 +2897,7 @@ PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const {      return ABIArgInfo::getDirect();    if (isAggregateTypeForABI(Ty)) { -    if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) +    if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))        return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);      return ABIArgInfo::getIndirect(0); @@ -2961,9 +3076,9 @@ public:              Env == "android" || Env == "androideabi");    } -private:    ABIKind getABIKind() const { return Kind; } +private:    ABIArgInfo classifyReturnType(QualType RetTy) const;    ABIArgInfo classifyArgumentType(QualType RetTy, int *VFPRegs,                                    unsigned &AllocatedVFP, @@ -3010,6 +3125,45 @@ public:      if (getABIInfo().isEABI()) return 88;      return TargetCodeGenInfo::getSizeOfUnwindException();    } + +  void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, +                           CodeGen::CodeGenModule &CGM) const { +    const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); +    if (!FD) +      return; + +    const ARMInterruptAttr *Attr = FD->getAttr<ARMInterruptAttr>(); +    if (!Attr) +      return; + +    const char *Kind; +    switch (Attr->getInterrupt()) { +    case ARMInterruptAttr::Generic: Kind = ""; break; +    case ARMInterruptAttr::IRQ:     Kind = "IRQ"; break; +    case ARMInterruptAttr::FIQ:     Kind = "FIQ"; break; +    case ARMInterruptAttr::SWI:     Kind = "SWI"; break; +    case ARMInterruptAttr::ABORT:   Kind = "ABORT"; break; +    case ARMInterruptAttr::UNDEF:   Kind = "UNDEF"; break; +    } + +    llvm::Function *Fn = cast<llvm::Function>(GV); + +    Fn->addFnAttr("interrupt", Kind); + +    if (cast<ARMABIInfo>(getABIInfo()).getABIKind() == ARMABIInfo::APCS) +      return; + +    // AAPCS guarantees that sp will be 8-byte aligned on any public interface, +    // however this is not necessarily true on taking any interrupt. Instruct +    // the backend to perform a realignment as part of the function prologue. +    llvm::AttrBuilder B; +    B.addStackAlignmentAttr(8); +    Fn->addAttributes(llvm::AttributeSet::FunctionIndex, +                      llvm::AttributeSet::get(CGM.getLLVMContext(), +                                              llvm::AttributeSet::FunctionIndex, +                                              B)); +  } +  };  } @@ -3243,13 +3397,13 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, int *VFPRegs,              ABIArgInfo::getExtend() : ABIArgInfo::getDirect());    } +  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) +    return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); +    // Ignore empty records.    if (isEmptyRecord(getContext(), Ty, true))      return ABIArgInfo::getIgnore(); -  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) -    return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); -    if (getABIKind() == ARMABIInfo::AAPCS_VFP) {      // Homogeneous Aggregates need to be expanded when we can fit the aggregate      // into VFP registers. @@ -3411,7 +3565,7 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const {    // Structures with either a non-trivial destructor or a non-trivial    // copy constructor are always indirect. -  if (isRecordReturnIndirect(RetTy, CGT)) +  if (isRecordReturnIndirect(RetTy, getCXXABI()))      return ABIArgInfo::getIndirect(0, /*ByVal=*/false);    // Are we following APCS? @@ -3496,6 +3650,12 @@ llvm::Value *ARMABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,    llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap");    llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); +  if (isEmptyRecord(getContext(), Ty, true)) { +    // These are ignored for parameter passing purposes. +    llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); +    return Builder.CreateBitCast(Addr, PTy); +  } +    uint64_t Size = CGF.getContext().getTypeSize(Ty) / 8;    uint64_t TyAlign = CGF.getContext().getTypeAlign(Ty) / 8;    bool IsIndirect = false; @@ -3735,7 +3895,7 @@ ABIArgInfo AArch64ABIInfo::classifyGenericType(QualType Ty,      return tryUseRegs(Ty, FreeIntRegs, RegsNeeded, /*IsInt=*/ true);    } -  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) { +  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {      if (FreeIntRegs > 0 && RAA == CGCXXABI::RAA_Indirect)        --FreeIntRegs;      return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); @@ -4037,16 +4197,26 @@ private:  ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const {    if (RetTy->isVoidType())      return ABIArgInfo::getIgnore(); -  if (isAggregateTypeForABI(RetTy)) -    return ABIArgInfo::getIndirect(0); -  return ABIArgInfo::getDirect(); + +  // note: this is different from default ABI +  if (!RetTy->isScalarType()) +    return ABIArgInfo::getDirect(); + +  // Treat an enum type as its underlying type. +  if (const EnumType *EnumTy = RetTy->getAs<EnumType>()) +    RetTy = EnumTy->getDecl()->getIntegerType(); + +  return (RetTy->isPromotableIntegerType() ? +          ABIArgInfo::getExtend() : ABIArgInfo::getDirect());  }  ABIArgInfo NVPTXABIInfo::classifyArgumentType(QualType Ty) const { -  if (isAggregateTypeForABI(Ty)) -    return ABIArgInfo::getIndirect(0); +  // Treat an enum type as its underlying type. +  if (const EnumType *EnumTy = Ty->getAs<EnumType>()) +    Ty = EnumTy->getDecl()->getIntegerType(); -  return ABIArgInfo::getDirect(); +  return (Ty->isPromotableIntegerType() ? +          ABIArgInfo::getExtend() : ABIArgInfo::getDirect());  }  void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const { @@ -4351,6 +4521,36 @@ llvm::Value *SystemZABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,    return ResAddr;  } +bool X86_32TargetCodeGenInfo::isStructReturnInRegABI( +    const llvm::Triple &Triple, const CodeGenOptions &Opts) { +  assert(Triple.getArch() == llvm::Triple::x86); + +  switch (Opts.getStructReturnConvention()) { +  case CodeGenOptions::SRCK_Default: +    break; +  case CodeGenOptions::SRCK_OnStack:  // -fpcc-struct-return +    return false; +  case CodeGenOptions::SRCK_InRegs:  // -freg-struct-return +    return true; +  } + +  if (Triple.isOSDarwin()) +    return true; + +  switch (Triple.getOS()) { +  case llvm::Triple::Cygwin: +  case llvm::Triple::MinGW32: +  case llvm::Triple::AuroraUX: +  case llvm::Triple::DragonFly: +  case llvm::Triple::FreeBSD: +  case llvm::Triple::OpenBSD: +  case llvm::Triple::Bitrig: +  case llvm::Triple::Win32: +    return true; +  default: +    return false; +  } +}  ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {    if (RetTy->isVoidType()) @@ -4363,7 +4563,7 @@ ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {  ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {    // Handle the generic C++ ABI. -  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) +  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))      return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);    // Integers and enums are extended to full register width. @@ -4373,7 +4573,7 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {    // Values that are not 1, 2, 4 or 8 bytes in size are passed indirectly.    uint64_t Size = getContext().getTypeSize(Ty);    if (Size != 8 && Size != 16 && Size != 32 && Size != 64) -    return ABIArgInfo::getIndirect(0); +    return ABIArgInfo::getIndirect(0, /*ByVal=*/false);    // Handle small structures.    if (const RecordType *RT = Ty->getAs<RecordType>()) { @@ -4381,7 +4581,7 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {      // fail the size test above.      const RecordDecl *RD = RT->getDecl();      if (RD->hasFlexibleArrayMember()) -      return ABIArgInfo::getIndirect(0); +      return ABIArgInfo::getIndirect(0, /*ByVal=*/false);      // The structure is passed as an unextended integer, a float, or a double.      llvm::Type *PassTy; @@ -4398,122 +4598,12 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {    // Non-structure compounds are passed indirectly.    if (isCompoundType(Ty)) -    return ABIArgInfo::getIndirect(0); +    return ABIArgInfo::getIndirect(0, /*ByVal=*/false);    return ABIArgInfo::getDirect(0);  }  //===----------------------------------------------------------------------===// -// MBlaze ABI Implementation -//===----------------------------------------------------------------------===// - -namespace { - -class MBlazeABIInfo : public ABIInfo { -public: -  MBlazeABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {} - -  bool isPromotableIntegerType(QualType Ty) const; - -  ABIArgInfo classifyReturnType(QualType RetTy) const; -  ABIArgInfo classifyArgumentType(QualType RetTy) const; - -  virtual void computeInfo(CGFunctionInfo &FI) const { -    FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); -    for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); -         it != ie; ++it) -      it->info = classifyArgumentType(it->type); -  } - -  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, -                                 CodeGenFunction &CGF) const; -}; - -class MBlazeTargetCodeGenInfo : public TargetCodeGenInfo { -public: -  MBlazeTargetCodeGenInfo(CodeGenTypes &CGT) -    : TargetCodeGenInfo(new MBlazeABIInfo(CGT)) {} -  void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, -                           CodeGen::CodeGenModule &M) const; -}; - -} - -bool MBlazeABIInfo::isPromotableIntegerType(QualType Ty) const { -  // MBlaze ABI requires all 8 and 16 bit quantities to be extended. -  if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) -    switch (BT->getKind()) { -    case BuiltinType::Bool: -    case BuiltinType::Char_S: -    case BuiltinType::Char_U: -    case BuiltinType::SChar: -    case BuiltinType::UChar: -    case BuiltinType::Short: -    case BuiltinType::UShort: -      return true; -    default: -      return false; -    } -  return false; -} - -llvm::Value *MBlazeABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, -                                      CodeGenFunction &CGF) const { -  // FIXME: Implement -  return 0; -} - - -ABIArgInfo MBlazeABIInfo::classifyReturnType(QualType RetTy) const { -  if (RetTy->isVoidType()) -    return ABIArgInfo::getIgnore(); -  if (isAggregateTypeForABI(RetTy)) -    return ABIArgInfo::getIndirect(0); - -  return (isPromotableIntegerType(RetTy) ? -          ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); -} - -ABIArgInfo MBlazeABIInfo::classifyArgumentType(QualType Ty) const { -  if (isAggregateTypeForABI(Ty)) -    return ABIArgInfo::getIndirect(0); - -  return (isPromotableIntegerType(Ty) ? -          ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); -} - -void MBlazeTargetCodeGenInfo::SetTargetAttributes(const Decl *D, -                                                  llvm::GlobalValue *GV, -                                                  CodeGen::CodeGenModule &M) -                                                  const { -  const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); -  if (!FD) return; - -  llvm::CallingConv::ID CC = llvm::CallingConv::C; -  if (FD->hasAttr<MBlazeInterruptHandlerAttr>()) -    CC = llvm::CallingConv::MBLAZE_INTR; -  else if (FD->hasAttr<MBlazeSaveVolatilesAttr>()) -    CC = llvm::CallingConv::MBLAZE_SVOL; - -  if (CC != llvm::CallingConv::C) { -      // Handle 'interrupt_handler' attribute: -      llvm::Function *F = cast<llvm::Function>(GV); - -      // Step 1: Set ISR calling convention. -      F->setCallingConv(CC); - -      // Step 2: Add attributes goodness. -      F->addFnAttr(llvm::Attribute::NoInline); -  } - -  // Step 3: Emit _interrupt_handler alias. -  if (CC == llvm::CallingConv::MBLAZE_INTR) -    new llvm::GlobalAlias(GV->getType(), llvm::Function::ExternalLinkage, -                          "_interrupt_handler", GV, &M.getModule()); -} - - -//===----------------------------------------------------------------------===//  // MSP430 ABI Implementation  //===----------------------------------------------------------------------===// @@ -4562,7 +4652,7 @@ class MipsABIInfo : public ABIInfo {    bool IsO32;    unsigned MinABIStackAlignInBytes, StackAlignInBytes;    void CoerceToIntArgs(uint64_t TySize, -                       SmallVector<llvm::Type*, 8> &ArgList) const; +                       SmallVectorImpl<llvm::Type *> &ArgList) const;    llvm::Type* HandleAggregates(QualType Ty, uint64_t TySize) const;    llvm::Type* returnAggregateInRegs(QualType RetTy, uint64_t Size) const;    llvm::Type* getPaddingType(uint64_t Align, uint64_t Offset) const; @@ -4612,7 +4702,7 @@ public:  }  void MipsABIInfo::CoerceToIntArgs(uint64_t TySize, -                                  SmallVector<llvm::Type*, 8> &ArgList) const { +                                  SmallVectorImpl<llvm::Type *> &ArgList) const {    llvm::IntegerType *IntTy =      llvm::IntegerType::get(getVMContext(), MinABIStackAlignInBytes * 8); @@ -4685,13 +4775,12 @@ llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty, uint64_t TySize) const {    return llvm::StructType::get(getVMContext(), ArgList);  } -llvm::Type *MipsABIInfo::getPaddingType(uint64_t Align, uint64_t Offset) const { -  assert((Offset % MinABIStackAlignInBytes) == 0); - -  if ((Align - 1) & Offset) -    return llvm::IntegerType::get(getVMContext(), MinABIStackAlignInBytes * 8); +llvm::Type *MipsABIInfo::getPaddingType(uint64_t OrigOffset, +                                        uint64_t Offset) const { +  if (OrigOffset + MinABIStackAlignInBytes > Offset) +    return 0; -  return 0; +  return llvm::IntegerType::get(getVMContext(), (Offset - OrigOffset) * 8);  }  ABIArgInfo @@ -4702,15 +4791,15 @@ MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const {    Align = std::min(std::max(Align, (uint64_t)MinABIStackAlignInBytes),                     (uint64_t)StackAlignInBytes); -  Offset = llvm::RoundUpToAlignment(Offset, Align); -  Offset += llvm::RoundUpToAlignment(TySize, Align * 8) / 8; +  unsigned CurrOffset = llvm::RoundUpToAlignment(Offset, Align); +  Offset = CurrOffset + llvm::RoundUpToAlignment(TySize, Align * 8) / 8;    if (isAggregateTypeForABI(Ty) || Ty->isVectorType()) {      // Ignore empty aggregates.      if (TySize == 0)        return ABIArgInfo::getIgnore(); -    if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) { +    if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {        Offset = OrigOffset + MinABIStackAlignInBytes;        return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);      } @@ -4719,7 +4808,7 @@ MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const {      // another structure type. Padding is inserted if the offset of the      // aggregate is unaligned.      return ABIArgInfo::getDirect(HandleAggregates(Ty, TySize), 0, -                                 getPaddingType(Align, OrigOffset)); +                                 getPaddingType(OrigOffset, CurrOffset));    }    // Treat an enum type as its underlying type. @@ -4729,8 +4818,8 @@ MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const {    if (Ty->isPromotableIntegerType())      return ABIArgInfo::getExtend(); -  return ABIArgInfo::getDirect(0, 0, -                               IsO32 ? 0 : getPaddingType(Align, OrigOffset)); +  return ABIArgInfo::getDirect( +      0, 0, IsO32 ? 0 : getPaddingType(OrigOffset, CurrOffset));  }  llvm::Type* @@ -4782,7 +4871,7 @@ ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const {      return ABIArgInfo::getIgnore();    if (isAggregateTypeForABI(RetTy) || RetTy->isVectorType()) { -    if (isRecordReturnIndirect(RetTy, CGT)) +    if (isRecordReturnIndirect(RetTy, getCXXABI()))        return ABIArgInfo::getIndirect(0);      if (Size <= 128) { @@ -5003,7 +5092,7 @@ ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty) const {    if (isEmptyRecord(getContext(), Ty, true))      return ABIArgInfo::getIgnore(); -  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) +  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))      return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);    uint64_t Size = getContext().getTypeSize(Ty); @@ -5039,7 +5128,7 @@ ABIArgInfo HexagonABIInfo::classifyReturnType(QualType RetTy) const {    // Structures with either a non-trivial destructor or a non-trivial    // copy constructor are always indirect. -  if (isRecordReturnIndirect(RetTy, CGT)) +  if (isRecordReturnIndirect(RetTy, getCXXABI()))      return ABIArgInfo::getIndirect(0, /*ByVal=*/false);    if (isEmptyRecord(getContext(), RetTy, true)) @@ -5086,6 +5175,335 @@ llvm::Value *HexagonABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,  } +//===----------------------------------------------------------------------===// +// SPARC v9 ABI Implementation. +// Based on the SPARC Compliance Definition version 2.4.1. +// +// Function arguments a mapped to a nominal "parameter array" and promoted to +// registers depending on their type. Each argument occupies 8 or 16 bytes in +// the array, structs larger than 16 bytes are passed indirectly. +// +// One case requires special care: +// +//   struct mixed { +//     int i; +//     float f; +//   }; +// +// When a struct mixed is passed by value, it only occupies 8 bytes in the +// parameter array, but the int is passed in an integer register, and the float +// is passed in a floating point register. This is represented as two arguments +// with the LLVM IR inreg attribute: +// +//   declare void f(i32 inreg %i, float inreg %f) +// +// The code generator will only allocate 4 bytes from the parameter array for +// the inreg arguments. All other arguments are allocated a multiple of 8 +// bytes. +// +namespace { +class SparcV9ABIInfo : public ABIInfo { +public: +  SparcV9ABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {} + +private: +  ABIArgInfo classifyType(QualType RetTy, unsigned SizeLimit) const; +  virtual void computeInfo(CGFunctionInfo &FI) const; +  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, +                                 CodeGenFunction &CGF) const; + +  // Coercion type builder for structs passed in registers. The coercion type +  // serves two purposes: +  // +  // 1. Pad structs to a multiple of 64 bits, so they are passed 'left-aligned' +  //    in registers. +  // 2. Expose aligned floating point elements as first-level elements, so the +  //    code generator knows to pass them in floating point registers. +  // +  // We also compute the InReg flag which indicates that the struct contains +  // aligned 32-bit floats. +  // +  struct CoerceBuilder { +    llvm::LLVMContext &Context; +    const llvm::DataLayout &DL; +    SmallVector<llvm::Type*, 8> Elems; +    uint64_t Size; +    bool InReg; + +    CoerceBuilder(llvm::LLVMContext &c, const llvm::DataLayout &dl) +      : Context(c), DL(dl), Size(0), InReg(false) {} + +    // Pad Elems with integers until Size is ToSize. +    void pad(uint64_t ToSize) { +      assert(ToSize >= Size && "Cannot remove elements"); +      if (ToSize == Size) +        return; + +      // Finish the current 64-bit word. +      uint64_t Aligned = llvm::RoundUpToAlignment(Size, 64); +      if (Aligned > Size && Aligned <= ToSize) { +        Elems.push_back(llvm::IntegerType::get(Context, Aligned - Size)); +        Size = Aligned; +      } + +      // Add whole 64-bit words. +      while (Size + 64 <= ToSize) { +        Elems.push_back(llvm::Type::getInt64Ty(Context)); +        Size += 64; +      } + +      // Final in-word padding. +      if (Size < ToSize) { +        Elems.push_back(llvm::IntegerType::get(Context, ToSize - Size)); +        Size = ToSize; +      } +    } + +    // Add a floating point element at Offset. +    void addFloat(uint64_t Offset, llvm::Type *Ty, unsigned Bits) { +      // Unaligned floats are treated as integers. +      if (Offset % Bits) +        return; +      // The InReg flag is only required if there are any floats < 64 bits. +      if (Bits < 64) +        InReg = true; +      pad(Offset); +      Elems.push_back(Ty); +      Size = Offset + Bits; +    } + +    // Add a struct type to the coercion type, starting at Offset (in bits). +    void addStruct(uint64_t Offset, llvm::StructType *StrTy) { +      const llvm::StructLayout *Layout = DL.getStructLayout(StrTy); +      for (unsigned i = 0, e = StrTy->getNumElements(); i != e; ++i) { +        llvm::Type *ElemTy = StrTy->getElementType(i); +        uint64_t ElemOffset = Offset + Layout->getElementOffsetInBits(i); +        switch (ElemTy->getTypeID()) { +        case llvm::Type::StructTyID: +          addStruct(ElemOffset, cast<llvm::StructType>(ElemTy)); +          break; +        case llvm::Type::FloatTyID: +          addFloat(ElemOffset, ElemTy, 32); +          break; +        case llvm::Type::DoubleTyID: +          addFloat(ElemOffset, ElemTy, 64); +          break; +        case llvm::Type::FP128TyID: +          addFloat(ElemOffset, ElemTy, 128); +          break; +        case llvm::Type::PointerTyID: +          if (ElemOffset % 64 == 0) { +            pad(ElemOffset); +            Elems.push_back(ElemTy); +            Size += 64; +          } +          break; +        default: +          break; +        } +      } +    } + +    // Check if Ty is a usable substitute for the coercion type. +    bool isUsableType(llvm::StructType *Ty) const { +      if (Ty->getNumElements() != Elems.size()) +        return false; +      for (unsigned i = 0, e = Elems.size(); i != e; ++i) +        if (Elems[i] != Ty->getElementType(i)) +          return false; +      return true; +    } + +    // Get the coercion type as a literal struct type. +    llvm::Type *getType() const { +      if (Elems.size() == 1) +        return Elems.front(); +      else +        return llvm::StructType::get(Context, Elems); +    } +  }; +}; +} // end anonymous namespace + +ABIArgInfo +SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit) const { +  if (Ty->isVoidType()) +    return ABIArgInfo::getIgnore(); + +  uint64_t Size = getContext().getTypeSize(Ty); + +  // Anything too big to fit in registers is passed with an explicit indirect +  // pointer / sret pointer. +  if (Size > SizeLimit) +    return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + +  // Treat an enum type as its underlying type. +  if (const EnumType *EnumTy = Ty->getAs<EnumType>()) +    Ty = EnumTy->getDecl()->getIntegerType(); + +  // Integer types smaller than a register are extended. +  if (Size < 64 && Ty->isIntegerType()) +    return ABIArgInfo::getExtend(); + +  // Other non-aggregates go in registers. +  if (!isAggregateTypeForABI(Ty)) +    return ABIArgInfo::getDirect(); + +  // This is a small aggregate type that should be passed in registers. +  // Build a coercion type from the LLVM struct type. +  llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty)); +  if (!StrTy) +    return ABIArgInfo::getDirect(); + +  CoerceBuilder CB(getVMContext(), getDataLayout()); +  CB.addStruct(0, StrTy); +  CB.pad(llvm::RoundUpToAlignment(CB.DL.getTypeSizeInBits(StrTy), 64)); + +  // Try to use the original type for coercion. +  llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType(); + +  if (CB.InReg) +    return ABIArgInfo::getDirectInReg(CoerceTy); +  else +    return ABIArgInfo::getDirect(CoerceTy); +} + +llvm::Value *SparcV9ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, +                                       CodeGenFunction &CGF) const { +  ABIArgInfo AI = classifyType(Ty, 16 * 8); +  llvm::Type *ArgTy = CGT.ConvertType(Ty); +  if (AI.canHaveCoerceToType() && !AI.getCoerceToType()) +    AI.setCoerceToType(ArgTy); + +  llvm::Type *BPP = CGF.Int8PtrPtrTy; +  CGBuilderTy &Builder = CGF.Builder; +  llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap"); +  llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); +  llvm::Type *ArgPtrTy = llvm::PointerType::getUnqual(ArgTy); +  llvm::Value *ArgAddr; +  unsigned Stride; + +  switch (AI.getKind()) { +  case ABIArgInfo::Expand: +    llvm_unreachable("Unsupported ABI kind for va_arg"); + +  case ABIArgInfo::Extend: +    Stride = 8; +    ArgAddr = Builder +      .CreateConstGEP1_32(Addr, 8 - getDataLayout().getTypeAllocSize(ArgTy), +                          "extend"); +    break; + +  case ABIArgInfo::Direct: +    Stride = getDataLayout().getTypeAllocSize(AI.getCoerceToType()); +    ArgAddr = Addr; +    break; + +  case ABIArgInfo::Indirect: +    Stride = 8; +    ArgAddr = Builder.CreateBitCast(Addr, +                                    llvm::PointerType::getUnqual(ArgPtrTy), +                                    "indirect"); +    ArgAddr = Builder.CreateLoad(ArgAddr, "indirect.arg"); +    break; + +  case ABIArgInfo::Ignore: +    return llvm::UndefValue::get(ArgPtrTy); +  } + +  // Update VAList. +  Addr = Builder.CreateConstGEP1_32(Addr, Stride, "ap.next"); +  Builder.CreateStore(Addr, VAListAddrAsBPP); + +  return Builder.CreatePointerCast(ArgAddr, ArgPtrTy, "arg.addr"); +} + +void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI) const { +  FI.getReturnInfo() = classifyType(FI.getReturnType(), 32 * 8); +  for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); +       it != ie; ++it) +    it->info = classifyType(it->type, 16 * 8); +} + +namespace { +class SparcV9TargetCodeGenInfo : public TargetCodeGenInfo { +public: +  SparcV9TargetCodeGenInfo(CodeGenTypes &CGT) +    : TargetCodeGenInfo(new SparcV9ABIInfo(CGT)) {} +}; +} // end anonymous namespace + + +//===----------------------------------------------------------------------===// +// Xcore ABI Implementation +//===----------------------------------------------------------------------===// +namespace { +class XCoreABIInfo : public DefaultABIInfo { +public: +  XCoreABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} +  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, +                                 CodeGenFunction &CGF) const; +}; + +class XcoreTargetCodeGenInfo : public TargetCodeGenInfo { +public: +  XcoreTargetCodeGenInfo(CodeGenTypes &CGT) +    :TargetCodeGenInfo(new XCoreABIInfo(CGT)) {} +}; +} // End anonymous namespace. + +llvm::Value *XCoreABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, +                                     CodeGenFunction &CGF) const { +  CGBuilderTy &Builder = CGF.Builder; + +  // Get the VAList. +  llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, +                                                       CGF.Int8PtrPtrTy); +  llvm::Value *AP = Builder.CreateLoad(VAListAddrAsBPP); + +  // Handle the argument. +  ABIArgInfo AI = classifyArgumentType(Ty); +  llvm::Type *ArgTy = CGT.ConvertType(Ty); +  if (AI.canHaveCoerceToType() && !AI.getCoerceToType()) +    AI.setCoerceToType(ArgTy); +  llvm::Type *ArgPtrTy = llvm::PointerType::getUnqual(ArgTy); +  llvm::Value *Val; +  uint64_t ArgSize = 0; +  switch (AI.getKind()) { +  case ABIArgInfo::Expand: +    llvm_unreachable("Unsupported ABI kind for va_arg"); +  case ABIArgInfo::Ignore: +    Val = llvm::UndefValue::get(ArgPtrTy); +    ArgSize = 0; +    break; +  case ABIArgInfo::Extend: +  case ABIArgInfo::Direct: +    Val = Builder.CreatePointerCast(AP, ArgPtrTy); +    ArgSize = getDataLayout().getTypeAllocSize(AI.getCoerceToType()); +    if (ArgSize < 4) +      ArgSize = 4; +    break; +  case ABIArgInfo::Indirect: +    llvm::Value *ArgAddr; +    ArgAddr = Builder.CreateBitCast(AP, llvm::PointerType::getUnqual(ArgPtrTy)); +    ArgAddr = Builder.CreateLoad(ArgAddr); +    Val = Builder.CreatePointerCast(ArgAddr, ArgPtrTy); +    ArgSize = 4; +    break; +  } + +  // Increment the VAList. +  if (ArgSize) { +    llvm::Value *APN = Builder.CreateConstGEP1_32(AP, ArgSize); +    Builder.CreateStore(APN, VAListAddrAsBPP); +  } +  return Val; +} + +//===----------------------------------------------------------------------===// +// Driver code +//===----------------------------------------------------------------------===// +  const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {    if (TheTargetCodeGenInfo)      return *TheTargetCodeGenInfo; @@ -5136,14 +5554,14 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {        return *(TheTargetCodeGenInfo = new PPC64_SVR4_TargetCodeGenInfo(Types));      else        return *(TheTargetCodeGenInfo = new PPC64TargetCodeGenInfo(Types)); +  case llvm::Triple::ppc64le: +    assert(Triple.isOSBinFormatELF() && "PPC64 LE non-ELF not supported!"); +    return *(TheTargetCodeGenInfo = new PPC64_SVR4_TargetCodeGenInfo(Types));    case llvm::Triple::nvptx:    case llvm::Triple::nvptx64:      return *(TheTargetCodeGenInfo = new NVPTXTargetCodeGenInfo(Types)); -  case llvm::Triple::mblaze: -    return *(TheTargetCodeGenInfo = new MBlazeTargetCodeGenInfo(Types)); -    case llvm::Triple::msp430:      return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo(Types)); @@ -5154,31 +5572,22 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {      return *(TheTargetCodeGenInfo = new TCETargetCodeGenInfo(Types));    case llvm::Triple::x86: { -    if (Triple.isOSDarwin()) -      return *(TheTargetCodeGenInfo = -               new X86_32TargetCodeGenInfo(Types, true, true, false, -                                           CodeGenOpts.NumRegisterParameters)); - -    switch (Triple.getOS()) { -    case llvm::Triple::Cygwin: -    case llvm::Triple::MinGW32: -    case llvm::Triple::AuroraUX: -    case llvm::Triple::DragonFly: -    case llvm::Triple::FreeBSD: -    case llvm::Triple::OpenBSD: -    case llvm::Triple::Bitrig: -      return *(TheTargetCodeGenInfo = -               new X86_32TargetCodeGenInfo(Types, false, true, false, -                                           CodeGenOpts.NumRegisterParameters)); +    bool IsDarwinVectorABI = Triple.isOSDarwin(); +    bool IsSmallStructInRegABI = +        X86_32TargetCodeGenInfo::isStructReturnInRegABI(Triple, CodeGenOpts); +    bool IsWin32FloatStructABI = (Triple.getOS() == llvm::Triple::Win32); -    case llvm::Triple::Win32: +    if (Triple.getOS() == llvm::Triple::Win32) {        return *(TheTargetCodeGenInfo = -               new X86_32TargetCodeGenInfo(Types, false, true, true, -                                           CodeGenOpts.NumRegisterParameters)); - -    default: +               new WinX86_32TargetCodeGenInfo(Types, +                                              IsDarwinVectorABI, IsSmallStructInRegABI, +                                              IsWin32FloatStructABI, +                                              CodeGenOpts.NumRegisterParameters)); +    } else {        return *(TheTargetCodeGenInfo = -               new X86_32TargetCodeGenInfo(Types, false, false, false, +               new X86_32TargetCodeGenInfo(Types, +                                           IsDarwinVectorABI, IsSmallStructInRegABI, +                                           IsWin32FloatStructABI,                                             CodeGenOpts.NumRegisterParameters));      }    } @@ -5201,5 +5610,10 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {    }    case llvm::Triple::hexagon:      return *(TheTargetCodeGenInfo = new HexagonTargetCodeGenInfo(Types)); +  case llvm::Triple::sparcv9: +    return *(TheTargetCodeGenInfo = new SparcV9TargetCodeGenInfo(Types)); +  case llvm::Triple::xcore: +    return *(TheTargetCodeGenInfo = new XcoreTargetCodeGenInfo(Types)); +    }  } diff --git a/lib/CodeGen/TargetInfo.h b/lib/CodeGen/TargetInfo.h index bb50ce69e3124..f631f3102d0d1 100644 --- a/lib/CodeGen/TargetInfo.h +++ b/lib/CodeGen/TargetInfo.h @@ -18,8 +18,10 @@  #include "clang/AST/Type.h"  #include "clang/Basic/LLVM.h"  #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallString.h"  namespace llvm { +  class Constant;    class GlobalValue;    class Type;    class Value; @@ -110,8 +112,13 @@ namespace clang {        return Address;      } +    /// Corrects the low-level LLVM type for a given constraint and "usual" +    /// type. +    /// +    /// \returns A pointer to a new LLVM type, possibly the same as the original +    /// on success; 0 on failure.      virtual llvm::Type* adjustInlineAsmType(CodeGen::CodeGenFunction &CGF, -                                            StringRef Constraint,  +                                            StringRef Constraint,                                              llvm::Type* Ty) const {        return Ty;      } @@ -130,6 +137,13 @@ namespace clang {        return "";      } +    /// Return a constant used by UBSan as a signature to identify functions +    /// possessing type information, or 0 if the platform is unsupported. +    virtual llvm::Constant *getUBSanFunctionSignature( +        CodeGen::CodeGenModule &CGM) const { +      return 0; +    } +      /// Determine whether a call to an unprototyped functions under      /// the given calling convention should use the variadic      /// convention or the non-variadic convention. @@ -165,8 +179,26 @@ namespace clang {      /// arguments in %al.  On these platforms, it is desireable to      /// call unprototyped functions using the variadic convention so      /// that unprototyped calls to varargs functions still succeed. +    /// +    /// Relatedly, platforms which pass the fixed arguments to this: +    ///   A foo(B, C, D); +    /// differently than they would pass them to this: +    ///   A foo(B, C, D, ...); +    /// may need to adjust the debugger-support code in Sema to do the +    /// right thing when calling a function with no know signature.      virtual bool isNoProtoCallVariadic(const CodeGen::CallArgList &args,                                         const FunctionNoProtoType *fnType) const; + +    /// Gets the linker options necessary to link a dependent library on this +    /// platform. +    virtual void getDependentLibraryOption(llvm::StringRef Lib, +                                           llvm::SmallString<24> &Opt) const; + +    /// Gets the linker options necessary to detect object file mismatches on +    /// this platform. +    virtual void getDetectMismatchOption(llvm::StringRef Name, +                                         llvm::StringRef Value, +                                         llvm::SmallString<32> &Opt) const {}    };  }  | 
