diff options
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.h')
| -rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 280 | 
1 files changed, 203 insertions, 77 deletions
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 6a1fa487ed14..ab5bbc03db95 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -76,6 +76,10 @@ class ObjCAtThrowStmt;  class ObjCAtSynchronizedStmt;  class ObjCAutoreleasePoolStmt; +namespace analyze_os_log { +class OSLogBufferLayout; +} +  namespace CodeGen {  class CodeGenTypes;  class CGCallee; @@ -111,6 +115,7 @@ enum TypeEvaluationKind {    SANITIZER_CHECK(DynamicTypeCacheMiss, dynamic_type_cache_miss, 0)            \    SANITIZER_CHECK(FloatCastOverflow, float_cast_overflow, 0)                   \    SANITIZER_CHECK(FunctionTypeMismatch, function_type_mismatch, 0)             \ +  SANITIZER_CHECK(InvalidBuiltin, invalid_builtin, 0)                          \    SANITIZER_CHECK(LoadInvalidValue, load_invalid_value, 0)                     \    SANITIZER_CHECK(MissingReturn, missing_return, 0)                            \    SANITIZER_CHECK(MulOverflow, mul_overflow, 0)                                \ @@ -220,6 +225,10 @@ public:    };    CGCoroInfo CurCoro; +  bool isCoroutine() const { +    return CurCoro.Data != nullptr; +  } +    /// CurGD - The GlobalDecl for the current function being compiled.    GlobalDecl CurGD; @@ -262,9 +271,9 @@ public:          if (I->capturesThis())            CXXThisFieldDecl = *Field;          else if (I->capturesVariable()) -          CaptureFields[I->getCapturedVar()] = *Field; +          CaptureFields[I->getCapturedVar()->getCanonicalDecl()] = *Field;          else if (I->capturesVariableByCopy()) -          CaptureFields[I->getCapturedVar()] = *Field; +          CaptureFields[I->getCapturedVar()->getCanonicalDecl()] = *Field;        }      } @@ -278,7 +287,7 @@ public:      /// \brief Lookup the captured field decl for a variable.      virtual const FieldDecl *lookup(const VarDecl *VD) const { -      return CaptureFields.lookup(VD); +      return CaptureFields.lookup(VD->getCanonicalDecl());      }      bool isCXXThisExprCaptured() const { return getThisFieldDecl() != nullptr; } @@ -708,6 +717,7 @@ public:                 llvm::function_ref<Address()> PrivateGen) {        assert(PerformCleanup && "adding private to dead scope"); +      LocalVD = LocalVD->getCanonicalDecl();        // Only save it once.        if (SavedLocals.count(LocalVD)) return false; @@ -758,8 +768,9 @@ public:          ForceCleanup();      } -    /// Checks if the global variable is captured in current function.  +    /// Checks if the global variable is captured in current function.      bool isGlobalVarCaptured(const VarDecl *VD) const { +      VD = VD->getCanonicalDecl();        return !VD->isLocalVarDeclOrParm() && CGF.LocalDeclMap.count(VD) > 0;      } @@ -819,7 +830,7 @@ public:    /// block through the normal cleanup handling code (if any) and then    /// on to \arg Dest.    void EmitBranchThroughCleanup(JumpDest Dest); -   +    /// isObviouslyBranchWithoutCleanups - Return true if a branch to the    /// specified destination obviously has no cleanups to run.  'false' is always    /// a conservatively correct answer for this method. @@ -1038,7 +1049,7 @@ public:        if (Data.isValid()) Data.unbind(CGF);      }    }; -   +  private:    CGDebugInfo *DebugInfo;    bool DisableDebugInfo; @@ -1156,19 +1167,6 @@ private:    };    OpenMPCancelExitStack OMPCancelStack; -  /// Controls insertion of cancellation exit blocks in worksharing constructs. -  class OMPCancelStackRAII { -    CodeGenFunction &CGF; - -  public: -    OMPCancelStackRAII(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, -                       bool HasCancel) -        : CGF(CGF) { -      CGF.OMPCancelStack.enter(CGF, Kind, HasCancel); -    } -    ~OMPCancelStackRAII() { CGF.OMPCancelStack.exit(CGF); } -  }; -    CodeGenPGO PGO;    /// Calculate branch weights appropriate for PGO data @@ -1427,7 +1425,7 @@ private:    /// Add OpenCL kernel arg metadata and the kernel attribute meatadata to    /// the function metadata. -  void EmitOpenCLKernelMetadata(const FunctionDecl *FD,  +  void EmitOpenCLKernelMetadata(const FunctionDecl *FD,                                  llvm::Function *Fn);  public: @@ -1436,10 +1434,10 @@ public:    CodeGenTypes &getTypes() const { return CGM.getTypes(); }    ASTContext &getContext() const { return CGM.getContext(); } -  CGDebugInfo *getDebugInfo() {  -    if (DisableDebugInfo)  +  CGDebugInfo *getDebugInfo() { +    if (DisableDebugInfo)        return nullptr; -    return DebugInfo;  +    return DebugInfo;    }    void disableDebugInfo() { DisableDebugInfo = true; }    void enableDebugInfo() { DisableDebugInfo = false; } @@ -1577,13 +1575,21 @@ public:    //                                  Block Bits    //===--------------------------------------------------------------------===// -  llvm::Value *EmitBlockLiteral(const BlockExpr *); +  /// Emit block literal. +  /// \return an LLVM value which is a pointer to a struct which contains +  /// information about the block, including the block invoke function, the +  /// captured variables, etc. +  /// \param InvokeF will contain the block invoke function if it is not +  /// nullptr. +  llvm::Value *EmitBlockLiteral(const BlockExpr *, +                                llvm::Function **InvokeF = nullptr);    static void destroyBlockInfos(CGBlockInfo *info);    llvm::Function *GenerateBlockFunction(GlobalDecl GD,                                          const CGBlockInfo &Info,                                          const DeclMapTy &ldm, -                                        bool IsLambdaConversionToBlock); +                                        bool IsLambdaConversionToBlock, +                                        bool BuildGlobalBlock);    llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo);    llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo); @@ -1642,10 +1648,9 @@ public:    void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator,                                    CallArgList &CallArgs); -  void EmitLambdaToBlockPointerBody(FunctionArgList &Args);    void EmitLambdaBlockInvokeBody();    void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD); -  void EmitLambdaStaticInvokeFunction(const CXXMethodDecl *MD); +  void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD);    void EmitAsanPrologueOrEpilogue(bool Prologue);    /// \brief Emit the unified return block, trying to avoid its emission when @@ -1766,13 +1771,18 @@ public:    /// instrumented with XRay nop sleds.    bool ShouldXRayInstrumentFunction() const; -  /// EmitFunctionInstrumentation - Emit LLVM code to call the specified -  /// instrumentation function with the current function and the call site, if -  /// function instrumentation is enabled. -  void EmitFunctionInstrumentation(const char *Fn); +  /// AlwaysEmitXRayCustomEvents - Return true if we must unconditionally emit +  /// XRay custom event handling calls. +  bool AlwaysEmitXRayCustomEvents() const; -  /// EmitMCountInstrumentation - Emit call to .mcount. -  void EmitMCountInstrumentation(); +  /// Encode an address into a form suitable for use in a function prologue. +  llvm::Constant *EncodeAddrForUseInPrologue(llvm::Function *F, +                                             llvm::Constant *Addr); + +  /// Decode an address used in a function prologue, encoded by \c +  /// EncodeAddrForUseInPrologue. +  llvm::Value *DecodeAddrUsedInPrologue(llvm::Value *F, +                                        llvm::Value *EncodedAddr);    /// EmitFunctionProlog - Emit the target specific LLVM code to load the    /// arguments for the given function. This is also responsible for naming the @@ -1816,8 +1826,7 @@ public:    /// TypeOfSelfObject - Return type of object that this self represents.    QualType TypeOfSelfObject(); -  /// hasAggregateLLVMType - Return true if the specified AST type will map into -  /// an aggregate LLVM type or is void. +  /// getEvaluationKind - Return the TypeEvaluationKind of QualType \c T.    static TypeEvaluationKind getEvaluationKind(QualType T);    static bool hasScalarEvaluationKind(QualType T) { @@ -1896,33 +1905,53 @@ public:    //===--------------------------------------------------------------------===//    LValue MakeAddrLValue(Address Addr, QualType T, -                        LValueBaseInfo BaseInfo = -                            LValueBaseInfo(AlignmentSource::Type)) { -    return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, -                            CGM.getTBAAInfo(T)); +                        AlignmentSource Source = AlignmentSource::Type) { +    return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source), +                            CGM.getTBAAAccessInfo(T)); +  } + +  LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo, +                        TBAAAccessInfo TBAAInfo) { +    return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, TBAAInfo);    }    LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, -                        LValueBaseInfo BaseInfo = -                            LValueBaseInfo(AlignmentSource::Type)) { +                        AlignmentSource Source = AlignmentSource::Type) {      return LValue::MakeAddr(Address(V, Alignment), T, getContext(), -                            BaseInfo, CGM.getTBAAInfo(T)); +                            LValueBaseInfo(Source), CGM.getTBAAAccessInfo(T)); +  } + +  LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, +                        LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { +    return LValue::MakeAddr(Address(V, Alignment), T, getContext(), +                            BaseInfo, TBAAInfo);    }    LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T);    LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T);    CharUnits getNaturalTypeAlignment(QualType T,                                      LValueBaseInfo *BaseInfo = nullptr, +                                    TBAAAccessInfo *TBAAInfo = nullptr,                                      bool forPointeeType = false);    CharUnits getNaturalPointeeTypeAlignment(QualType T, -                                           LValueBaseInfo *BaseInfo = nullptr); - -  Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy, -                              LValueBaseInfo *BaseInfo = nullptr); -  LValue EmitLoadOfReferenceLValue(Address Ref, const ReferenceType *RefTy); +                                           LValueBaseInfo *BaseInfo = nullptr, +                                           TBAAAccessInfo *TBAAInfo = nullptr); + +  Address EmitLoadOfReference(LValue RefLVal, +                              LValueBaseInfo *PointeeBaseInfo = nullptr, +                              TBAAAccessInfo *PointeeTBAAInfo = nullptr); +  LValue EmitLoadOfReferenceLValue(LValue RefLVal); +  LValue EmitLoadOfReferenceLValue(Address RefAddr, QualType RefTy, +                                   AlignmentSource Source = +                                       AlignmentSource::Type) { +    LValue RefLVal = MakeAddrLValue(RefAddr, RefTy, LValueBaseInfo(Source), +                                    CGM.getTBAAAccessInfo(RefTy)); +    return EmitLoadOfReferenceLValue(RefLVal); +  }    Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, -                            LValueBaseInfo *BaseInfo = nullptr); +                            LValueBaseInfo *BaseInfo = nullptr, +                            TBAAAccessInfo *TBAAInfo = nullptr);    LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy);    /// CreateTempAlloca - This creates an alloca and inserts it into the entry @@ -2345,6 +2374,12 @@ public:      TCK_NonnullAssign    }; +  /// Determine whether the pointer type check \p TCK permits null pointers. +  static bool isNullPointerAllowed(TypeCheckKind TCK); + +  /// Determine whether the pointer type check \p TCK requires a vptr check. +  static bool isVptrCheckRequired(TypeCheckKind TCK, QualType Ty); +    /// \brief Whether any type-checking sanitizers are enabled. If \c false,    /// calls to EmitTypeCheck can be skipped.    bool sanitizePerformTypeCheck() const; @@ -2464,7 +2499,7 @@ public:    };    AutoVarEmission EmitAutoVarAlloca(const VarDecl &var);    void EmitAutoVarInit(const AutoVarEmission &emission); -  void EmitAutoVarCleanups(const AutoVarEmission &emission);   +  void EmitAutoVarCleanups(const AutoVarEmission &emission);    void emitAutoVarTypeCleanup(const AutoVarEmission &emission,                                QualType::DestructionKind dtorKind); @@ -2486,7 +2521,7 @@ public:      bool isIndirect() const { return Alignment != 0; }      llvm::Value *getAnyValue() const { return Value; } -     +      llvm::Value *getDirectValue() const {        assert(!isIndirect());        return Value; @@ -2532,7 +2567,7 @@ public:    /// This function may clear the current insertion point; callers should use    /// EnsureInsertPoint if they wish to subsequently generate code without first    /// calling EmitBlock, EmitBranch, or EmitStmt. -  void EmitStmt(const Stmt *S); +  void EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs = None);    /// EmitSimpleStmt - Try to emit a "simple" statement which does not    /// necessarily require an insertion point or debug information; typically @@ -2635,6 +2670,19 @@ public:    void EmitCXXForRangeStmt(const CXXForRangeStmt &S,                             ArrayRef<const Attr *> Attrs = None); +  /// Controls insertion of cancellation exit blocks in worksharing constructs. +  class OMPCancelStackRAII { +    CodeGenFunction &CGF; + +  public: +    OMPCancelStackRAII(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, +                       bool HasCancel) +        : CGF(CGF) { +      CGF.OMPCancelStack.enter(CGF, Kind, HasCancel); +    } +    ~OMPCancelStackRAII() { CGF.OMPCancelStack.exit(CGF); } +  }; +    /// Returns calculated size of the specified type.    llvm::Value *getTypeSize(QualType Ty);    LValue InitCapturedStruct(const CapturedStmt &S); @@ -2841,9 +2889,30 @@ public:    static void    EmitOMPTargetParallelDeviceFunction(CodeGenModule &CGM, StringRef ParentName,                                        const OMPTargetParallelDirective &S); +  /// Emit device code for the target parallel for directive. +  static void EmitOMPTargetParallelForDeviceFunction( +      CodeGenModule &CGM, StringRef ParentName, +      const OMPTargetParallelForDirective &S); +  /// Emit device code for the target parallel for simd directive. +  static void EmitOMPTargetParallelForSimdDeviceFunction( +      CodeGenModule &CGM, StringRef ParentName, +      const OMPTargetParallelForSimdDirective &S); +  /// Emit device code for the target teams directive.    static void    EmitOMPTargetTeamsDeviceFunction(CodeGenModule &CGM, StringRef ParentName,                                     const OMPTargetTeamsDirective &S); +  /// Emit device code for the target teams distribute directive. +  static void EmitOMPTargetTeamsDistributeDeviceFunction( +      CodeGenModule &CGM, StringRef ParentName, +      const OMPTargetTeamsDistributeDirective &S); +  /// Emit device code for the target teams distribute simd directive. +  static void EmitOMPTargetTeamsDistributeSimdDeviceFunction( +      CodeGenModule &CGM, StringRef ParentName, +      const OMPTargetTeamsDistributeSimdDirective &S); +  /// Emit device code for the target simd directive. +  static void EmitOMPTargetSimdDeviceFunction(CodeGenModule &CGM, +                                              StringRef ParentName, +                                              const OMPTargetSimdDirective &S);    /// \brief Emit inner loop of the worksharing/simd construct.    ///    /// \param S Directive, for which the inner loop must be emitted. @@ -2875,9 +2944,9 @@ public:                                const CodeGenLoopBoundsTy &CodeGenLoopBounds,                                const CodeGenDispatchBoundsTy &CGDispatchBounds); -private: -  /// Helpers for blocks -  llvm::Value *EmitBlockLiteral(const CGBlockInfo &Info); +  /// Emit code for the distribute loop-based directive. +  void EmitOMPDistributeLoop(const OMPLoopDirective &S, +                             const CodeGenLoopTy &CodeGenLoop, Expr *IncExpr);    /// Helpers for the OpenMP loop directives.    void EmitOMPSimdInit(const OMPLoopDirective &D, bool IsMonotonic = false); @@ -2885,8 +2954,15 @@ private:        const OMPLoopDirective &D,        const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen); -  void EmitOMPDistributeLoop(const OMPLoopDirective &S, -                             const CodeGenLoopTy &CodeGenLoop, Expr *IncExpr); +  /// Emits the lvalue for the expression with possibly captured variable. +  LValue EmitOMPSharedLValue(const Expr *E); + +private: +  /// Helpers for blocks. Returns invoke function by \p InvokeF if it is not +  /// nullptr. It should be called without \p InvokeF if the caller does not +  /// need invoke function to be returned. +  llvm::Value *EmitBlockLiteral(const CGBlockInfo &Info, +                                llvm::Function **InvokeF = nullptr);    /// struct with the values to be passed to the OpenMP loop-related functions    struct OMPLoopArguments { @@ -3034,11 +3110,15 @@ public:    /// the LLVM value representation.    llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty,                                  SourceLocation Loc, -                                LValueBaseInfo BaseInfo = -                                    LValueBaseInfo(AlignmentSource::Type), -                                llvm::MDNode *TBAAInfo = nullptr, -                                QualType TBAABaseTy = QualType(), -                                uint64_t TBAAOffset = 0, +                                AlignmentSource Source = AlignmentSource::Type, +                                bool isNontemporal = false) { +    return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, LValueBaseInfo(Source), +                            CGM.getTBAAAccessInfo(Ty), isNontemporal); +  } + +  llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, +                                SourceLocation Loc, LValueBaseInfo BaseInfo, +                                TBAAAccessInfo TBAAInfo,                                  bool isNontemporal = false);    /// EmitLoadOfScalar - Load a scalar value from an address, taking @@ -3052,11 +3132,16 @@ public:    /// the LLVM value representation.    void EmitStoreOfScalar(llvm::Value *Value, Address Addr,                           bool Volatile, QualType Ty, -                         LValueBaseInfo BaseInfo = -                             LValueBaseInfo(AlignmentSource::Type), -                         llvm::MDNode *TBAAInfo = nullptr, bool isInit = false, -                         QualType TBAABaseTy = QualType(), -                         uint64_t TBAAOffset = 0, bool isNontemporal = false); +                         AlignmentSource Source = AlignmentSource::Type, +                         bool isInit = false, bool isNontemporal = false) { +    EmitStoreOfScalar(Value, Addr, Volatile, Ty, LValueBaseInfo(Source), +                      CGM.getTBAAAccessInfo(Ty), isInit, isNontemporal); +  } + +  void EmitStoreOfScalar(llvm::Value *Value, Address Addr, +                         bool Volatile, QualType Ty, +                         LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, +                         bool isInit = false, bool isNontemporal = false);    /// EmitStoreOfScalar - Store a scalar value to an address, taking    /// care to appropriately convert from the memory representation to @@ -3120,13 +3205,14 @@ public:    LValue EmitCastLValue(const CastExpr *E);    LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);    LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e); -   +    Address EmitExtVectorElementLValue(LValue V);    RValue EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc);    Address EmitArrayToPointerDecay(const Expr *Array, -                                  LValueBaseInfo *BaseInfo = nullptr); +                                  LValueBaseInfo *BaseInfo = nullptr, +                                  TBAAAccessInfo *TBAAInfo = nullptr);    class ConstantEmission {      llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference; @@ -3159,6 +3245,7 @@ public:    };    ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr); +  ConstantEmission tryEmitAsConstant(const MemberExpr *ME);    RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e,                                  AggValueSlot slot = AggValueSlot::ignored()); @@ -3235,12 +3322,12 @@ public:    void EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee,                                         ArrayRef<llvm::Value*> args); -  CGCallee BuildAppleKextVirtualCall(const CXXMethodDecl *MD,  +  CGCallee BuildAppleKextVirtualCall(const CXXMethodDecl *MD,                                       NestedNameSpecifier *Qual,                                       llvm::Type *Ty); -   +    CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD, -                                               CXXDtorType Type,  +                                               CXXDtorType Type,                                                 const CXXRecordDecl *RD);    RValue @@ -3267,7 +3354,8 @@ public:    Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base,                                            llvm::Value *memberPtr,                                            const MemberPointerType *memberPtrType, -                                          LValueBaseInfo *BaseInfo = nullptr); +                                          LValueBaseInfo *BaseInfo = nullptr, +                                          TBAAAccessInfo *TBAAInfo = nullptr);    RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,                                        ReturnValueSlot ReturnValue); @@ -3286,6 +3374,13 @@ public:                           unsigned BuiltinID, const CallExpr *E,                           ReturnValueSlot ReturnValue); +  /// Emit IR for __builtin_os_log_format. +  RValue emitBuiltinOSLogFormat(const CallExpr &E); + +  llvm::Function *generateBuiltinOSLogHelperFunction( +      const analyze_os_log::OSLogBufferLayout &Layout, +      CharUnits BufferAlignment); +    RValue EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue);    /// EmitTargetBuiltinExpr - Emit the given builtin call. Returns 0 if the call @@ -3329,6 +3424,7 @@ public:    llvm::Value *EmitNVPTXBuiltinExpr(unsigned BuiltinID, const CallExpr *E);    llvm::Value *EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,                                            const CallExpr *E); +  llvm::Value *EmitHexagonBuiltinExpr(unsigned BuiltinID, const CallExpr *E);  private:    enum class MSVCIntrin; @@ -3406,11 +3502,11 @@ public:    static Destroyer destroyARCWeak;    static Destroyer emitARCIntrinsicUse; -  void EmitObjCAutoreleasePoolPop(llvm::Value *Ptr);  +  void EmitObjCAutoreleasePoolPop(llvm::Value *Ptr);    llvm::Value *EmitObjCAutoreleasePoolPush();    llvm::Value *EmitObjCMRRAutoreleasePoolPush();    void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr); -  void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr);  +  void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr);    /// \brief Emits a reference binding to the passed in expression.    RValue EmitReferenceBindingToExpr(const Expr *E); @@ -3498,6 +3594,14 @@ public:    void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr,                            bool PerformInit); +  enum class GuardKind { VariableGuard, TlsGuard }; + +  /// Emit a branch to select whether or not to perform guarded initialization. +  void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit, +                                llvm::BasicBlock *InitBlock, +                                llvm::BasicBlock *NoInitBlock, +                                GuardKind Kind, const VarDecl *D); +    /// GenerateCXXGlobalInitFunc - Generates code for initializing global    /// variables.    void GenerateCXXGlobalInitFunc(llvm::Function *Fn, @@ -3517,7 +3621,7 @@ public:                                          bool PerformInit);    void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest); -   +    void EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp);    void enterFullExpression(const ExprWithCleanups *E) { @@ -3566,7 +3670,7 @@ public:    /// Determine if the given statement might introduce a declaration into the    /// current scope, by being a (possibly-labelled) DeclStmt.    static bool mightAddDeclToScope(const Stmt *S); -   +    /// ConstantFoldsToSimpleInteger - If the specified expression does not fold    /// to a constant, or if it does but contains a label, return false.  If it    /// constant folds return true and set the boolean result in Result. @@ -3607,6 +3711,17 @@ public:                                        SourceLocation Loc,                                        const Twine &Name = ""); +  /// Specifies which type of sanitizer check to apply when handling a +  /// particular builtin. +  enum BuiltinCheckKind { +    BCK_CTZPassedZero, +    BCK_CLZPassedZero, +  }; + +  /// Emits an argument for a call to a builtin. If the builtin sanitizer is +  /// enabled, a runtime check specified by \p Kind is also emitted. +  llvm::Value *EmitCheckedArgForBuiltin(const Expr *E, BuiltinCheckKind Kind); +    /// \brief Emit a description of a type in a format suitable for passing to    /// a runtime sanitizer handler.    llvm::Constant *EmitCheckTypeDescriptor(QualType T); @@ -3820,7 +3935,13 @@ public:    /// reasonable to just ignore the returned alignment when it isn't from an    /// explicit source.    Address EmitPointerWithAlignment(const Expr *Addr, -                                   LValueBaseInfo *BaseInfo = nullptr); +                                   LValueBaseInfo *BaseInfo = nullptr, +                                   TBAAAccessInfo *TBAAInfo = nullptr); + +  /// If \p E references a parameter with pass_object_size info or a constant +  /// array size modifier, emit the object size divided by the size of \p EltTy. +  /// Otherwise return null. +  llvm::Value *LoadPassedObjectSize(const Expr *E, QualType EltTy);    void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK); @@ -3835,6 +3956,11 @@ private:    void AddObjCARCExceptionMetadata(llvm::Instruction *Inst);    llvm::Value *GetValueForARMHint(unsigned BuiltinID); +  llvm::Value *EmitX86CpuIs(const CallExpr *E); +  llvm::Value *EmitX86CpuIs(StringRef CPUStr); +  llvm::Value *EmitX86CpuSupports(const CallExpr *E); +  llvm::Value *EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs); +  llvm::Value *EmitX86CpuInit();  };  /// Helper class with most of the code for saving a value for a  | 
