diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2012-04-14 14:01:31 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2012-04-14 14:01:31 +0000 |
commit | dbe13110f59f48b4dbb7552b3ac2935acdeece7f (patch) | |
tree | be1815eb79b42ff482a8562b13c2dcbf0c5dcbee /lib/CodeGen/CodeGenFunction.h | |
parent | 9da628931ebf2609493570f87824ca22402cc65f (diff) | |
download | src-dbe13110f59f48b4dbb7552b3ac2935acdeece7f.tar.gz src-dbe13110f59f48b4dbb7552b3ac2935acdeece7f.zip |
Vendor import of clang trunk r154661:vendor/clang/clang-trunk-r154661
Notes
Notes:
svn path=/vendor/clang/dist/; revision=234287
svn path=/vendor/clang/clang-trunk-r154661/; revision=234288; tag=vendor/clang/clang-trunk-r154661
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.h')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 407 |
1 files changed, 298 insertions, 109 deletions
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 157623da8fdd..3e0cd146256f 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -25,8 +25,10 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ValueHandle.h" +#include "llvm/Support/Debug.h" #include "CodeGenModule.h" #include "CGBuilder.h" +#include "CGDebugInfo.h" #include "CGValue.h" namespace llvm { @@ -41,8 +43,8 @@ namespace llvm { } namespace clang { - class APValue; class ASTContext; + class BlockDecl; class CXXDestructorDecl; class CXXForRangeStmt; class CXXTryStmt; @@ -69,7 +71,6 @@ namespace clang { namespace CodeGen { class CodeGenTypes; - class CGDebugInfo; class CGFunctionInfo; class CGRecordLayout; class CGBlockInfo; @@ -598,6 +599,9 @@ public: const CodeGen::CGBlockInfo *BlockInfo; llvm::Value *BlockPointer; + llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields; + FieldDecl *LambdaThisCaptureField; + /// \brief A mapping from NRVO variables to the flags used to indicate /// when the NRVO has been applied to this variable. llvm::DenseMap<const VarDecl *, llvm::Value *> NRVOFlags; @@ -609,6 +613,9 @@ public: unsigned NextCleanupDestIndex; + /// FirstBlockInfo - The head of a singly-linked-list of block layouts. + CGBlockInfo *FirstBlockInfo; + /// EHResumeBlock - Unified block containing a call to llvm.eh.resume. llvm::BasicBlock *EHResumeBlock; @@ -625,10 +632,6 @@ public: llvm::BasicBlock *getInvokeDestImpl(); - /// Set up the last cleaup that was pushed as a conditional - /// full-expression cleanup. - void initFullExprCleanup(); - template <class T> typename DominatingValue<T>::saved_type saveValueInCond(T value) { return DominatingValue<T>::save(*this, value); @@ -739,6 +742,10 @@ public: initFullExprCleanup(); } + /// Set up the last cleaup that was pushed as a conditional + /// full-expression cleanup. + void initFullExprCleanup(); + /// PushDestructorCleanup - Push a cleanup to call the /// complete-object destructor of an object of the given type at the /// given address. Does nothing if T is not a C++ class type with a @@ -758,16 +765,27 @@ public: /// DeactivateCleanupBlock - Deactivates the given cleanup block. /// The block cannot be reactivated. Pops it if it's the top of the /// stack. - void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup); + /// + /// \param DominatingIP - An instruction which is known to + /// dominate the current IP (if set) and which lies along + /// all paths of execution between the current IP and the + /// the point at which the cleanup comes into scope. + void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, + llvm::Instruction *DominatingIP); /// ActivateCleanupBlock - Activates an initially-inactive cleanup. /// Cannot be used to resurrect a deactivated cleanup. - void ActivateCleanupBlock(EHScopeStack::stable_iterator Cleanup); + /// + /// \param DominatingIP - An instruction which is known to + /// dominate the current IP (if set) and which lies along + /// all paths of execution between the current IP and the + /// the point at which the cleanup comes into scope. + void ActivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, + llvm::Instruction *DominatingIP); /// \brief Enters a new scope for capturing cleanups, all of which /// will be executed once the scope is exited. class RunCleanupsScope { - CodeGenFunction& CGF; EHScopeStack::stable_iterator CleanupStackDepth; bool OldDidCallStackSave; bool PerformCleanup; @@ -775,10 +793,13 @@ public: RunCleanupsScope(const RunCleanupsScope &); // DO NOT IMPLEMENT RunCleanupsScope &operator=(const RunCleanupsScope &); // DO NOT IMPLEMENT + protected: + CodeGenFunction& CGF; + public: /// \brief Enter a new cleanup scope. explicit RunCleanupsScope(CodeGenFunction &CGF) - : CGF(CGF), PerformCleanup(true) + : PerformCleanup(true), CGF(CGF) { CleanupStackDepth = CGF.EHStack.stable_begin(); OldDidCallStackSave = CGF.DidCallStackSave; @@ -809,6 +830,41 @@ public: } }; + class LexicalScope: protected RunCleanupsScope { + SourceRange Range; + bool PopDebugStack; + + LexicalScope(const LexicalScope &); // DO NOT IMPLEMENT THESE + LexicalScope &operator=(const LexicalScope &); + + public: + /// \brief Enter a new cleanup scope. + explicit LexicalScope(CodeGenFunction &CGF, SourceRange Range) + : RunCleanupsScope(CGF), Range(Range), PopDebugStack(true) { + if (CGDebugInfo *DI = CGF.getDebugInfo()) + DI->EmitLexicalBlockStart(CGF.Builder, Range.getBegin()); + } + + /// \brief Exit this cleanup scope, emitting any accumulated + /// cleanups. + ~LexicalScope() { + if (PopDebugStack) { + CGDebugInfo *DI = CGF.getDebugInfo(); + if (DI) DI->EmitLexicalBlockEnd(CGF.Builder, Range.getEnd()); + } + } + + /// \brief Force the emission of cleanups now, instead of waiting + /// until this object is destroyed. + void ForceCleanup() { + RunCleanupsScope::ForceCleanup(); + if (CGDebugInfo *DI = CGF.getDebugInfo()) { + DI->EmitLexicalBlockEnd(CGF.Builder, Range.getEnd()); + PopDebugStack = false; + } + } + }; + /// PopCleanupBlocks - Takes the old cleanup stack size and emits /// the cleanup blocks that have been added. @@ -881,6 +937,12 @@ public: /// one branch or the other of a conditional expression. bool isInConditionalBranch() const { return OutermostConditional != 0; } + void setBeforeOutermostConditional(llvm::Value *value, llvm::Value *addr) { + assert(isInConditionalBranch()); + llvm::BasicBlock *block = OutermostConditional->getStartingBlock(); + new llvm::StoreInst(value, addr, &block->back()); + } + /// An RAII object to record that we're evaluating a statement /// expression. class StmtExprEvaluation { @@ -912,18 +974,91 @@ public: public: PeepholeProtection() : Inst(0) {} - }; + }; - /// An RAII object to set (and then clear) a mapping for an OpaqueValueExpr. - class OpaqueValueMapping { - CodeGenFunction &CGF; + /// A non-RAII class containing all the information about a bound + /// opaque value. OpaqueValueMapping, below, is a RAII wrapper for + /// this which makes individual mappings very simple; using this + /// class directly is useful when you have a variable number of + /// opaque values or don't want the RAII functionality for some + /// reason. + class OpaqueValueMappingData { const OpaqueValueExpr *OpaqueValue; bool BoundLValue; CodeGenFunction::PeepholeProtection Protection; + OpaqueValueMappingData(const OpaqueValueExpr *ov, + bool boundLValue) + : OpaqueValue(ov), BoundLValue(boundLValue) {} + public: + OpaqueValueMappingData() : OpaqueValue(0) {} + + static bool shouldBindAsLValue(const Expr *expr) { + // gl-values should be bound as l-values for obvious reasons. + // Records should be bound as l-values because IR generation + // always keeps them in memory. Expressions of function type + // act exactly like l-values but are formally required to be + // r-values in C. + return expr->isGLValue() || + expr->getType()->isRecordType() || + expr->getType()->isFunctionType(); + } + + static OpaqueValueMappingData bind(CodeGenFunction &CGF, + const OpaqueValueExpr *ov, + const Expr *e) { + if (shouldBindAsLValue(ov)) + return bind(CGF, ov, CGF.EmitLValue(e)); + return bind(CGF, ov, CGF.EmitAnyExpr(e)); + } + + static OpaqueValueMappingData bind(CodeGenFunction &CGF, + const OpaqueValueExpr *ov, + const LValue &lv) { + assert(shouldBindAsLValue(ov)); + CGF.OpaqueLValues.insert(std::make_pair(ov, lv)); + return OpaqueValueMappingData(ov, true); + } + + static OpaqueValueMappingData bind(CodeGenFunction &CGF, + const OpaqueValueExpr *ov, + const RValue &rv) { + assert(!shouldBindAsLValue(ov)); + CGF.OpaqueRValues.insert(std::make_pair(ov, rv)); + + OpaqueValueMappingData data(ov, false); + + // Work around an extremely aggressive peephole optimization in + // EmitScalarConversion which assumes that all other uses of a + // value are extant. + data.Protection = CGF.protectFromPeepholes(rv); + + return data; + } + + bool isValid() const { return OpaqueValue != 0; } + void clear() { OpaqueValue = 0; } + + void unbind(CodeGenFunction &CGF) { + assert(OpaqueValue && "no data to unbind!"); + + if (BoundLValue) { + CGF.OpaqueLValues.erase(OpaqueValue); + } else { + CGF.OpaqueRValues.erase(OpaqueValue); + CGF.unprotectFromPeepholes(Protection); + } + } + }; + + /// An RAII object to set (and then clear) a mapping for an OpaqueValueExpr. + class OpaqueValueMapping { + CodeGenFunction &CGF; + OpaqueValueMappingData Data; + public: static bool shouldBindAsLValue(const Expr *expr) { - return expr->isGLValue() || expr->getType()->isRecordType(); + return OpaqueValueMappingData::shouldBindAsLValue(expr); } /// Build the opaque value mapping for the given conditional @@ -933,75 +1068,34 @@ public: /// OpaqueValueMapping(CodeGenFunction &CGF, const AbstractConditionalOperator *op) : CGF(CGF) { - if (isa<ConditionalOperator>(op)) { - OpaqueValue = 0; - BoundLValue = false; + if (isa<ConditionalOperator>(op)) + // Leave Data empty. return; - } const BinaryConditionalOperator *e = cast<BinaryConditionalOperator>(op); - init(e->getOpaqueValue(), e->getCommon()); + Data = OpaqueValueMappingData::bind(CGF, e->getOpaqueValue(), + e->getCommon()); } OpaqueValueMapping(CodeGenFunction &CGF, const OpaqueValueExpr *opaqueValue, LValue lvalue) - : CGF(CGF), OpaqueValue(opaqueValue), BoundLValue(true) { - assert(opaqueValue && "no opaque value expression!"); - assert(shouldBindAsLValue(opaqueValue)); - initLValue(lvalue); + : CGF(CGF), Data(OpaqueValueMappingData::bind(CGF, opaqueValue, lvalue)) { } OpaqueValueMapping(CodeGenFunction &CGF, const OpaqueValueExpr *opaqueValue, RValue rvalue) - : CGF(CGF), OpaqueValue(opaqueValue), BoundLValue(false) { - assert(opaqueValue && "no opaque value expression!"); - assert(!shouldBindAsLValue(opaqueValue)); - initRValue(rvalue); + : CGF(CGF), Data(OpaqueValueMappingData::bind(CGF, opaqueValue, rvalue)) { } void pop() { - assert(OpaqueValue && "mapping already popped!"); - popImpl(); - OpaqueValue = 0; + Data.unbind(CGF); + Data.clear(); } ~OpaqueValueMapping() { - if (OpaqueValue) popImpl(); - } - - private: - void popImpl() { - if (BoundLValue) - CGF.OpaqueLValues.erase(OpaqueValue); - else { - CGF.OpaqueRValues.erase(OpaqueValue); - CGF.unprotectFromPeepholes(Protection); - } - } - - void init(const OpaqueValueExpr *ov, const Expr *e) { - OpaqueValue = ov; - BoundLValue = shouldBindAsLValue(ov); - assert(BoundLValue == shouldBindAsLValue(e) - && "inconsistent expression value kinds!"); - if (BoundLValue) - initLValue(CGF.EmitLValue(e)); - else - initRValue(CGF.EmitAnyExpr(e)); - } - - void initLValue(const LValue &lv) { - CGF.OpaqueLValues.insert(std::make_pair(OpaqueValue, lv)); - } - - void initRValue(const RValue &rv) { - // Work around an extremely aggressive peephole optimization in - // EmitScalarConversion which assumes that all other uses of a - // value are extant. - Protection = CGF.protectFromPeepholes(rv); - CGF.OpaqueRValues.insert(std::make_pair(OpaqueValue, rv)); + if (Data.isValid()) Data.unbind(CGF); } }; @@ -1046,7 +1140,7 @@ private: }; SmallVector<BreakContinue, 8> BreakContinueStack; - /// SwitchInsn - This is nearest current switch instruction. It is null if if + /// SwitchInsn - This is nearest current switch instruction. It is null if /// current context is not in a switch. llvm::SwitchInst *SwitchInsn; @@ -1073,7 +1167,8 @@ private: /// CXXThisDecl - When generating code for a C++ member function, /// this will hold the implicit 'this' declaration. - ImplicitParamDecl *CXXThisDecl; + ImplicitParamDecl *CXXABIThisDecl; + llvm::Value *CXXABIThisValue; llvm::Value *CXXThisValue; /// CXXVTTDecl - When generating code for a base object constructor or @@ -1099,6 +1194,7 @@ private: public: CodeGenFunction(CodeGenModule &cgm); + ~CodeGenFunction(); CodeGenTypes &getTypes() const { return CGM.getTypes(); } ASTContext &getContext() const { return CGM.getContext(); } @@ -1114,7 +1210,7 @@ public: return CGM.getCodeGenOpts().OptimizationLevel == 0; } - const LangOptions &getLangOptions() const { return CGM.getLangOptions(); } + const LangOptions &getLangOpts() const { return CGM.getLangOpts(); } /// Returns a pointer to the function's exception object and selector slot, /// which is assigned in every landing pad. @@ -1152,27 +1248,27 @@ public: void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin, llvm::Value *arrayEndPointer, QualType elementType, - Destroyer &destroyer); + Destroyer *destroyer); void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, llvm::Value *arrayEnd, QualType elementType, - Destroyer &destroyer); + Destroyer *destroyer); void pushDestroy(QualType::DestructionKind dtorKind, llvm::Value *addr, QualType type); void pushDestroy(CleanupKind kind, llvm::Value *addr, QualType type, - Destroyer &destroyer, bool useEHCleanupForArray); - void emitDestroy(llvm::Value *addr, QualType type, Destroyer &destroyer, + Destroyer *destroyer, bool useEHCleanupForArray); + void emitDestroy(llvm::Value *addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray); llvm::Function *generateDestroyHelper(llvm::Constant *addr, QualType type, - Destroyer &destroyer, + Destroyer *destroyer, bool useEHCleanupForArray); void emitArrayDestroy(llvm::Value *begin, llvm::Value *end, - QualType type, Destroyer &destroyer, + QualType type, Destroyer *destroyer, bool checkZeroLength, bool useEHCleanup); - Destroyer &getDestroyer(QualType::DestructionKind destructionKind); + Destroyer *getDestroyer(QualType::DestructionKind destructionKind); /// Determines whether an EH cleanup is required to destroy a type /// with the given destruction kind. @@ -1182,9 +1278,9 @@ public: return false; case QualType::DK_cxx_destructor: case QualType::DK_objc_weak_lifetime: - return getLangOptions().Exceptions; + return getLangOpts().Exceptions; case QualType::DK_objc_strong_lifetime: - return getLangOptions().Exceptions && + return getLangOpts().Exceptions && CGM.getCodeGenOpts().ObjCAutoRefCountExceptions; } llvm_unreachable("bad destruction kind"); @@ -1208,7 +1304,8 @@ public: void GenerateObjCGetter(ObjCImplementationDecl *IMP, const ObjCPropertyImplDecl *PID); void generateObjCGetterBody(const ObjCImplementationDecl *classImpl, - const ObjCPropertyImplDecl *propImpl); + const ObjCPropertyImplDecl *propImpl, + llvm::Constant *AtomicHelperFn); void GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP, ObjCMethodDecl *MD, bool ctor); @@ -1218,7 +1315,8 @@ public: void GenerateObjCSetter(ObjCImplementationDecl *IMP, const ObjCPropertyImplDecl *PID); void generateObjCSetterBody(const ObjCImplementationDecl *classImpl, - const ObjCPropertyImplDecl *propImpl); + const ObjCPropertyImplDecl *propImpl, + llvm::Constant *AtomicHelperFn); bool IndirectObjCSetterArg(const CGFunctionInfo &FI); bool IvarTypeWithAggrGCObjects(QualType Ty); @@ -1227,6 +1325,8 @@ public: //===--------------------------------------------------------------------===// llvm::Value *EmitBlockLiteral(const BlockExpr *); + llvm::Value *EmitBlockLiteral(const CGBlockInfo &Info); + static void destroyBlockInfos(CGBlockInfo *info); llvm::Constant *BuildDescriptorBlockDecl(const BlockExpr *, const CGBlockInfo &Info, llvm::StructType *, @@ -1235,10 +1335,16 @@ public: llvm::Function *GenerateBlockFunction(GlobalDecl GD, const CGBlockInfo &Info, const Decl *OuterFuncDecl, - const DeclMapTy &ldm); + const DeclMapTy &ldm, + bool IsLambdaConversionToBlock); llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo); llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo); + llvm::Constant *GenerateObjCAtomicSetterCopyHelperFunction( + const ObjCPropertyImplDecl *PID); + llvm::Constant *GenerateObjCAtomicGetterCopyHelperFunction( + const ObjCPropertyImplDecl *PID); + llvm::Value *EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty); void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags); @@ -1253,10 +1359,7 @@ public: } void AllocateBlockCXXThisPointer(const CXXThisExpr *E); - void AllocateBlockDecl(const BlockDeclRefExpr *E); - llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E) { - return GetAddrOfBlockDecl(E->getDecl(), E->isByRef()); - } + void AllocateBlockDecl(const DeclRefExpr *E); llvm::Value *GetAddrOfBlockDecl(const VarDecl *var, bool ByRef); llvm::Type *BuildByRefType(const VarDecl *var); @@ -1272,6 +1375,13 @@ public: void EmitDestructorBody(FunctionArgList &Args); void EmitFunctionBody(FunctionArgList &Args); + void EmitForwardingCallToLambda(const CXXRecordDecl *Lambda, + CallArgList &CallArgs); + void EmitLambdaToBlockPointerBody(FunctionArgList &Args); + void EmitLambdaBlockInvokeBody(); + void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD); + void EmitLambdaStaticInvokeFunction(const CXXMethodDecl *MD); + /// EmitReturnBlock - Emit the unified return block, trying to avoid its /// emission when possible. void EmitReturnBlock(); @@ -1290,6 +1400,9 @@ public: void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type, FunctionArgList &Args); + void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init, + ArrayRef<VarDecl *> ArrayIndexes); + /// InitializeVTablePointer - Initialize the vtable pointer of the given /// subobject. /// @@ -1442,7 +1555,15 @@ public: // Helpers //===--------------------------------------------------------------------===// - LValue MakeAddrLValue(llvm::Value *V, QualType T, unsigned Alignment = 0) { + LValue MakeAddrLValue(llvm::Value *V, QualType T, + CharUnits Alignment = CharUnits()) { + return LValue::MakeAddr(V, T, Alignment, getContext(), + CGM.getTBAAInfo(T)); + } + LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) { + CharUnits Alignment; + if (!T->isIncompleteType()) + Alignment = getContext().getTypeAlignInChars(T); return LValue::MakeAddr(V, T, Alignment, getContext(), CGM.getTBAAInfo(T)); } @@ -1470,7 +1591,9 @@ public: /// CreateAggTemp - Create a temporary memory object for the given /// aggregate type. AggValueSlot CreateAggTemp(QualType T, const Twine &Name = "tmp") { - return AggValueSlot::forAddr(CreateMemTemp(T, Name), T.getQualifiers(), + CharUnits Alignment = getContext().getTypeAlignInChars(T); + return AggValueSlot::forAddr(CreateMemTemp(T, Name), Alignment, + T.getQualifiers(), AggValueSlot::IsNotDestructed, AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased); @@ -1519,7 +1642,8 @@ public: /// \param isVolatile - True iff either the source or the destination is /// volatile. void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr, - QualType EltTy, bool isVolatile=false); + QualType EltTy, bool isVolatile=false, + unsigned Alignment = 0); /// StartBlock - Start new block named N. If insert block is a dummy block /// then reuse it. @@ -1677,7 +1801,8 @@ public: void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType, llvm::Value *NewPtr, llvm::Value *NumElements); - void EmitCXXTemporary(const CXXTemporary *Temporary, llvm::Value *Ptr); + void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType, + llvm::Value *Ptr); llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E); void EmitCXXDeleteExpr(const CXXDeleteExpr *E); @@ -1688,6 +1813,10 @@ public: llvm::Value* EmitCXXTypeidExpr(const CXXTypeidExpr *E); llvm::Value *EmitDynamicCast(llvm::Value *V, const CXXDynamicCastExpr *DCE); + void MaybeEmitStdInitializerListCleanup(llvm::Value *loc, const Expr *init); + void EmitStdInitializerListCleanup(llvm::Value *loc, + const InitListExpr *init); + void EmitCheck(llvm::Value *, unsigned Size); llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, @@ -1917,13 +2046,14 @@ public: /// the LLVM value representation. void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, - llvm::MDNode *TBAAInfo = 0); + llvm::MDNode *TBAAInfo = 0, bool isInit=false); /// EmitStoreOfScalar - Store a scalar value to an address, taking /// care to appropriately convert from the memory representation to /// the LLVM value representation. The l-value must be a simple - /// l-value. - void EmitStoreOfScalar(llvm::Value *value, LValue lvalue); + /// l-value. The isInit flag indicates whether this is an initialization. + /// If so, atomic qualifiers are ignored and the store is always non-atomic. + void EmitStoreOfScalar(llvm::Value *value, LValue lvalue, bool isInit=false); /// EmitLoadOfLValue - Given an expression that represents a value lvalue, /// this method emits the address of the lvalue, then loads the result as an @@ -1931,15 +2061,12 @@ public: RValue EmitLoadOfLValue(LValue V); RValue EmitLoadOfExtVectorElementLValue(LValue V); RValue EmitLoadOfBitfieldLValue(LValue LV); - RValue EmitLoadOfPropertyRefLValue(LValue LV, - ReturnValueSlot Return = ReturnValueSlot()); /// 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 EmitStoreThroughLValue(RValue Src, LValue Dst); + void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false); void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst); - void EmitStoreThroughPropertyRefLValue(RValue Src, LValue Dst); /// EmitStoreThroughLValue - Store Src into Dst with same constraints as /// EmitStoreThroughLValue. @@ -1977,6 +2104,40 @@ public: LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E); LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e); + class ConstantEmission { + llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference; + ConstantEmission(llvm::Constant *C, bool isReference) + : ValueAndIsReference(C, isReference) {} + public: + ConstantEmission() {} + static ConstantEmission forReference(llvm::Constant *C) { + return ConstantEmission(C, true); + } + static ConstantEmission forValue(llvm::Constant *C) { + return ConstantEmission(C, false); + } + + operator bool() const { return ValueAndIsReference.getOpaqueValue() != 0; } + + bool isReference() const { return ValueAndIsReference.getInt(); } + LValue getReferenceLValue(CodeGenFunction &CGF, Expr *refExpr) const { + assert(isReference()); + return CGF.MakeNaturalAlignAddrLValue(ValueAndIsReference.getPointer(), + refExpr->getType()); + } + + llvm::Constant *getValue() const { + assert(!isReference()); + return ValueAndIsReference.getPointer(); + } + }; + + ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr); + + RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, + AggValueSlot slot = AggValueSlot::ignored()); + LValue EmitPseudoObjectLValue(const PseudoObjectExpr *e); + llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar); LValue EmitLValueForAnonRecordField(llvm::Value* Base, @@ -1999,16 +2160,13 @@ public: LValue EmitLValueForBitfield(llvm::Value* Base, const FieldDecl* Field, unsigned CVRQualifiers); - LValue EmitBlockDeclRefLValue(const BlockDeclRefExpr *E); - LValue EmitCXXConstructLValue(const CXXConstructExpr *E); LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E); - LValue EmitExprWithCleanupsLValue(const ExprWithCleanups *E); + LValue EmitLambdaLValue(const LambdaExpr *E); LValue EmitCXXTypeidLValue(const CXXTypeidExpr *E); LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E); LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E); - LValue EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E); LValue EmitStmtExprLValue(const StmtExpr *E); LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E); LValue EmitObjCSelectorLValue(const ObjCSelectorExpr *E); @@ -2098,12 +2256,18 @@ public: llvm::Value *EmitNeonShiftVector(llvm::Value *V, llvm::Type *Ty, bool negateForRightShift); - llvm::Value *BuildVector(const SmallVectorImpl<llvm::Value*> &Ops); + llvm::Value *BuildVector(ArrayRef<llvm::Value*> Ops); llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E); + llvm::Value *EmitHexagonBuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E); llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E); + llvm::Value *EmitObjCNumericLiteral(const ObjCNumericLiteral *E); + llvm::Value *EmitObjCArrayLiteral(const ObjCArrayLiteral *E); + llvm::Value *EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E); + llvm::Value *EmitObjCCollectionLiteral(const Expr *E, + const ObjCMethodDecl *MethodWithObjects); llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E); RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return = ReturnValueSlot()); @@ -2243,7 +2407,8 @@ public: /// EmitCXXGlobalVarDeclInit - Create the initializer for a C++ /// variable with global storage. - void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr); + void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, + bool PerformInit); /// EmitCXXGlobalDtorRegistration - Emits a call to register the global ptr /// with the C++ runtime so that its destructor will be called at exit. @@ -2255,7 +2420,8 @@ public: /// possible to prove that an initialization will be done exactly /// once, e.g. with a static local variable or a static data member /// of a class template. - void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr); + void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr, + bool PerformInit); /// GenerateCXXGlobalInitFunc - Generates code for initializing global /// variables. @@ -2263,26 +2429,32 @@ public: llvm::Constant **Decls, unsigned NumDecls); - /// GenerateCXXGlobalDtorFunc - Generates code for destroying global + /// GenerateCXXGlobalDtorsFunc - Generates code for destroying global /// variables. - void GenerateCXXGlobalDtorFunc(llvm::Function *Fn, - const std::vector<std::pair<llvm::WeakVH, - llvm::Constant*> > &DtorsAndObjects); + void GenerateCXXGlobalDtorsFunc(llvm::Function *Fn, + const std::vector<std::pair<llvm::WeakVH, + llvm::Constant*> > &DtorsAndObjects); void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, const VarDecl *D, - llvm::GlobalVariable *Addr); + llvm::GlobalVariable *Addr, + bool PerformInit); void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest); void EmitSynthesizedCXXCopyCtor(llvm::Value *Dest, llvm::Value *Src, const Expr *Exp); - RValue EmitExprWithCleanups(const ExprWithCleanups *E, - AggValueSlot Slot =AggValueSlot::ignored()); + void enterFullExpression(const ExprWithCleanups *E) { + if (E->getNumObjects() == 0) return; + enterNonTrivialFullExpression(E); + } + void enterNonTrivialFullExpression(const ExprWithCleanups *E); void EmitCXXThrowExpr(const CXXThrowExpr *E); + void EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Dest); + RValue EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest = 0); //===--------------------------------------------------------------------===// @@ -2344,7 +2516,12 @@ public: /// a r-value suitable for passing the given parameter. void EmitDelegateCallArg(CallArgList &args, const VarDecl *param); + /// SetFPAccuracy - Set the minimum required accuracy of the given floating + /// point operation, expressed as the maximum relative error in ulp. + void SetFPAccuracy(llvm::Value *Val, float Accuracy); + private: + llvm::MDNode *getRangeForLoadFromType(QualType Ty); void EmitReturnOfRValue(RValue RV, QualType Ty); /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty @@ -2432,6 +2609,18 @@ private: CodeGenModule::ByrefHelpers * buildByrefHelpers(llvm::StructType &byrefType, const AutoVarEmission &emission); + + void AddObjCARCExceptionMetadata(llvm::Instruction *Inst); + + /// GetPointeeAlignment - Given an expression with a pointer type, find the + /// alignment of the type referenced by the pointer. Skip over implicit + /// casts. + unsigned GetPointeeAlignment(const Expr *Addr); + + /// GetPointeeAlignmentValue - Given an expression with a pointer type, find + /// the alignment of the type referenced by the pointer. Skip over implicit + /// casts. Return the alignment as an llvm::Value. + llvm::Value *GetPointeeAlignmentValue(const Expr *Addr); }; /// Helper class with most of the code for saving a value for a |