summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CodeGenFunction.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.h')
-rw-r--r--lib/CodeGen/CodeGenFunction.h97
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
OpenPOWER on IntegriCloud