summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp66
1 files changed, 49 insertions, 17 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp
index 2c3cabe..75c60ed 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -31,8 +31,7 @@ using namespace clang;
using namespace CodeGen;
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
- : CodeGenTypeCache(cgm), CGM(cgm),
- Target(CGM.getContext().getTargetInfo()),
+ : CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),
Builder(cgm.getModule().getContext()),
SanitizePerformTypeCheck(CGM.getSanOpts().Null |
CGM.getSanOpts().Alignment |
@@ -45,7 +44,9 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
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) {
@@ -91,6 +92,9 @@ TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) {
#include "clang/AST/TypeNodes.def"
llvm_unreachable("non-canonical or dependent type in IR-generation");
+ case Type::Auto:
+ llvm_unreachable("undeduced auto type in IR-generation");
+
// Various scalar types.
case Type::Builtin:
case Type::Pointer:
@@ -184,15 +188,36 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
assert(BreakContinueStack.empty() &&
"mismatched push/pop in break/continue stack!");
- if (CGDebugInfo *DI = getDebugInfo())
- DI->EmitLocation(Builder, EndLoc);
+ 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.
+ if (CGDebugInfo *DI = getDebugInfo()) {
+ if (OnlySimpleReturnStmts)
+ DI->EmitLocation(Builder, LastStopPoint);
+ else
+ DI->EmitLocation(Builder, EndLoc);
+ }
// Pop any cleanups that might have been associated with the
// parameters. Do this in whatever block we're currently in; it's
// important to do this before we enter the return block or return
// edges will be *really* confused.
- if (EHStack.stable_begin() != PrologueCleanupDepth)
- PopCleanupBlocks(PrologueCleanupDepth);
+ bool EmitRetDbgLoc = true;
+ if (EHStack.stable_begin() != PrologueCleanupDepth) {
+ PopCleanupBlocks(PrologueCleanupDepth, EndLoc);
+
+ // Make sure the line table doesn't jump back into the body for
+ // the ret after it's been at EndLoc.
+ EmitRetDbgLoc = false;
+
+ if (CGDebugInfo *DI = getDebugInfo())
+ if (OnlySimpleReturnStmts)
+ DI->EmitLocation(Builder, EndLoc);
+ }
// Emit function epilog (to return).
EmitReturnBlock();
@@ -205,7 +230,7 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
DI->EmitFunctionEnd(Builder);
}
- EmitFunctionEpilog(*CurFnInfo);
+ EmitFunctionEpilog(*CurFnInfo, EmitRetDbgLoc);
EmitEndEHSpec(CurCodeDecl);
assert(EHStack.empty() &&
@@ -279,8 +304,8 @@ void CodeGenFunction::EmitFunctionInstrumentation(const char *Fn) {
void CodeGenFunction::EmitMCountInstrumentation() {
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
- llvm::Constant *MCountFn = CGM.CreateRuntimeFunction(FTy,
- Target.getMCountName());
+ llvm::Constant *MCountFn =
+ CGM.CreateRuntimeFunction(FTy, getTarget().getMCountName());
EmitNounwindRuntimeCall(MCountFn);
}
@@ -448,7 +473,8 @@ void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD,
OpenCLKernelMetadata->addOperand(kernelMDNode);
}
-void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
+void CodeGenFunction::StartFunction(GlobalDecl GD,
+ QualType RetTy,
llvm::Function *Fn,
const CGFunctionInfo &FnInfo,
const FunctionArgList &Args,
@@ -456,7 +482,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
const Decl *D = GD.getDecl();
DidCallStackSave = false;
- CurCodeDecl = CurFuncDecl = D;
+ CurCodeDecl = D;
+ CurFuncDecl = (D ? D->getNonClosureContext() : 0);
FnRetTy = RetTy;
CurFn = Fn;
CurFnInfo = &FnInfo;
@@ -555,12 +582,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
LambdaThisCaptureField);
if (LambdaThisCaptureField) {
// If this lambda captures this, load it.
- QualType LambdaTagType =
- getContext().getTagDeclType(LambdaThisCaptureField->getParent());
- LValue LambdaLV = MakeNaturalAlignAddrLValue(CXXABIThisValue,
- LambdaTagType);
- LValue ThisLValue = EmitLValueForField(LambdaLV,
- LambdaThisCaptureField);
+ LValue ThisLValue = EmitLValueForLambdaField(LambdaThisCaptureField);
CXXThisValue = EmitLoadOfLValue(ThisLValue).getScalarVal();
}
} else {
@@ -906,6 +928,16 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
return;
}
+ if (const CXXThrowExpr *Throw = dyn_cast<CXXThrowExpr>(Cond)) {
+ // Conditional operator handling can give us a throw expression as a
+ // condition for a case like:
+ // br(c ? throw x : y, t, f) -> br(c, br(throw x, t, f), br(y, t, f)
+ // Fold this to:
+ // br(c, throw x, br(y, t, f))
+ EmitCXXThrowExpr(Throw, /*KeepInsertionPoint*/false);
+ return;
+ }
+
// Emit the code with the fully general case.
llvm::Value *CondV = EvaluateExprAsBool(Cond);
Builder.CreateCondBr(CondV, TrueBlock, FalseBlock);
OpenPOWER on IntegriCloud