diff options
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.h')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 97 |
1 files changed, 67 insertions, 30 deletions
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index be646fb..169c576 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -25,7 +25,6 @@ #include "llvm/Support/ValueHandle.h" #include "CodeGenModule.h" #include "CGBuilder.h" -#include "CGCall.h" #include "CGValue.h" namespace llvm { @@ -43,6 +42,7 @@ namespace clang { class APValue; class ASTContext; class CXXDestructorDecl; + class CXXForRangeStmt; class CXXTryStmt; class Decl; class LabelDecl; @@ -769,6 +769,11 @@ 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. + bool isObviouslyBranchWithoutCleanups(JumpDest Dest) const; /// EmitBranchThroughEHCleanup - Emit a branch from the current /// insert block through the EH cleanup handling code (if any) and @@ -944,6 +949,7 @@ public: const VarDecl *V); private: CGDebugInfo *DebugInfo; + bool DisableDebugInfo; /// IndirectBranch - The first time an indirect goto is seen we create a block /// with an indirect branch. Every time we see the address of a label taken, @@ -1030,7 +1036,14 @@ public: CodeGenTypes &getTypes() const { return CGM.getTypes(); } ASTContext &getContext() const; - CGDebugInfo *getDebugInfo() { return DebugInfo; } + CGDebugInfo *getDebugInfo() { + if (DisableDebugInfo) + return NULL; + return DebugInfo; + } + void disableDebugInfo() { DisableDebugInfo = true; } + void enableDebugInfo() { DisableDebugInfo = false; } + const LangOptions &getLangOptions() const { return CGM.getLangOptions(); } @@ -1100,15 +1113,13 @@ public: llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo); llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo); - llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, - BlockFieldFlags flags, - const VarDecl *BD); - llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, - BlockFieldFlags flags, - const VarDecl *BD); - void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags); + class AutoVarEmission; + + void emitByrefStructureInit(const AutoVarEmission &emission); + void enterByrefCleanup(const AutoVarEmission &emission); + llvm::Value *LoadBlockStruct() { assert(BlockPointer && "no block pointer set!"); return BlockPointer; @@ -1122,9 +1133,11 @@ public: llvm::Value *GetAddrOfBlockDecl(const VarDecl *var, bool ByRef); const llvm::Type *BuildByRefType(const VarDecl *var); - void GenerateCode(GlobalDecl GD, llvm::Function *Fn); + void GenerateCode(GlobalDecl GD, llvm::Function *Fn, + const CGFunctionInfo &FnInfo); void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, + const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation StartLoc); @@ -1141,7 +1154,8 @@ public: void FinishFunction(SourceLocation EndLoc=SourceLocation()); /// GenerateThunk - Generate a thunk for the given method. - void GenerateThunk(llvm::Function *Fn, GlobalDecl GD, const ThunkInfo &Thunk); + void GenerateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, + GlobalDecl GD, const ThunkInfo &Thunk); void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type, FunctionArgList &Args); @@ -1151,14 +1165,14 @@ public: /// void InitializeVTablePointer(BaseSubobject Base, const CXXRecordDecl *NearestVBase, - uint64_t OffsetFromNearestVBase, + CharUnits OffsetFromNearestVBase, llvm::Constant *VTable, const CXXRecordDecl *VTableClass); typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; void InitializeVTablePointers(BaseSubobject Base, const CXXRecordDecl *NearestVBase, - uint64_t OffsetFromNearestVBase, + CharUnits OffsetFromNearestVBase, bool BaseIsNonVirtualPrimaryBase, llvm::Constant *VTable, const CXXRecordDecl *VTableClass, @@ -1353,12 +1367,18 @@ public: /// always be accessible even if no aggregate location is provided. RValue EmitAnyExprToTemp(const Expr *E); - /// EmitsAnyExprToMem - Emits the code necessary to evaluate an + /// EmitAnyExprToMem - Emits the code necessary to evaluate an /// arbitrary expression into the given memory location. void EmitAnyExprToMem(const Expr *E, llvm::Value *Location, bool IsLocationVolatile, bool IsInitializer); + /// EmitExprAsInit - Emits the code necessary to initialize a + /// location in memory with the given initializer. + void EmitExprAsInit(const Expr *init, const VarDecl *var, + llvm::Value *loc, CharUnits alignment, + bool capturedByInit); + /// EmitAggregateCopy - Emit an aggrate copy. /// /// \param isVolatile - True iff either the source or the destination is @@ -1476,6 +1496,12 @@ public: void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, CXXCtorType CtorType, const FunctionArgList &Args); + // 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 + // they are substantially the same. + void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, + const FunctionArgList &Args); void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, llvm::Value *This, CallExpr::const_arg_iterator ArgBeg, @@ -1609,7 +1635,7 @@ public: llvm::GlobalValue::LinkageTypes Linkage); /// EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl. - void EmitParmDecl(const VarDecl &D, llvm::Value *Arg); + void EmitParmDecl(const VarDecl &D, llvm::Value *Arg, unsigned ArgNo); /// protectFromPeepholes - Protect a value that we're intending to /// store to the side, but which will probably be used later, from @@ -1680,6 +1706,7 @@ public: void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false); void EmitCXXTryStmt(const CXXTryStmt &S); + void EmitCXXForRangeStmt(const CXXForRangeStmt &S); //===--------------------------------------------------------------------===// // LValue Expression Emission @@ -1775,7 +1802,7 @@ public: LValue EmitComplexAssignmentLValue(const BinaryOperator *E); LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E); - // Note: only availabe for agg return types + // Note: only available for agg return types LValue EmitBinaryOperatorLValue(const BinaryOperator *E); LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E); // Note: only available for agg return types @@ -2022,7 +2049,8 @@ public: const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> > &DtorsAndObjects); - void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, const VarDecl *D, + void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, + const VarDecl *D, llvm::GlobalVariable *Addr); void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest); @@ -2044,12 +2072,21 @@ public: /// that we can just remove the code. static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false); + /// containsBreak - Return true if the statement contains a break out of it. + /// If the statement (recursively) contains a switch or loop with a break + /// inside of it, this is fine. + static bool containsBreak(const Stmt *S); + /// ConstantFoldsToSimpleInteger - If the specified expression does not fold - /// to a constant, or if it does but contains a label, return 0. If it - /// constant folds to 'true' and does not contain a label, return 1, if it - /// constant folds to 'false' and does not contain a label, return -1. - int ConstantFoldsToSimpleInteger(const Expr *Cond); + /// 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. + bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result); + /// 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 folded value. + bool ConstantFoldsToSimpleInteger(const Expr *Cond, llvm::APInt &Result); + /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an /// if statement) to the specified blocks. Based on the condition, this might /// try to simplify the codegen of the conditional based on the branch. @@ -2061,12 +2098,12 @@ public: llvm::BasicBlock *getTrapBB(); /// EmitCallArg - Emit a single call argument. - RValue EmitCallArg(const Expr *E, QualType ArgType); + void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType); /// 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. - RValue EmitDelegateCallArg(const VarDecl *Param); + void EmitDelegateCallArg(CallArgList &args, const VarDecl *param); private: void EmitReturnOfRValue(RValue RV, QualType Ty); @@ -2131,8 +2168,7 @@ private: getContext().getCanonicalType(ActualArgType).getTypePtr() && "type mismatch in call argument!"); #endif - Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType), - ArgType)); + EmitCallArg(Args, *Arg, ArgType); } // Either we've emitted all the call args, or we have a call to a @@ -2143,11 +2179,8 @@ private: } // If we still have any arguments, emit them using the type of the argument. - for (; Arg != ArgEnd; ++Arg) { - QualType ArgType = Arg->getType(); - Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType), - ArgType)); - } + for (; Arg != ArgEnd; ++Arg) + EmitCallArg(Args, *Arg, Arg->getType()); } const TargetCodeGenInfo &getTargetHooks() const { @@ -2155,6 +2188,10 @@ private: } void EmitDeclMetadata(); + + CodeGenModule::ByrefHelpers * + buildByrefHelpers(const llvm::StructType &byrefType, + const AutoVarEmission &emission); }; /// Helper class with most of the code for saving a value for a |