summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGClass.cpp2
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp32
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h2
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp6
5 files changed, 34 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index af8cbbc48c2..4848d7565d4 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2180,7 +2180,7 @@ void CodeGenFunction::EmitLambdaToBlockPointerBody(FunctionArgList &Args) {
return;
}
- EmitFunctionBody(Args);
+ EmitFunctionBody(Args, cast<FunctionDecl>(CurGD.getDecl())->getBody());
}
void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) {
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 221d132ee0b..4a427d540f6 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1824,8 +1824,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
return LV;
}
- if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(ND))
- return EmitFunctionDeclLValue(*this, E, fn);
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
+ return EmitFunctionDeclLValue(*this, E, FD);
llvm_unreachable("Unhandled DeclRefExpr");
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 3ec890383c9..ce1b44559dc 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -643,13 +643,12 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
DI->EmitLocation(Builder, StartLoc);
}
-void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args) {
- const FunctionDecl *FD = cast<FunctionDecl>(CurGD.getDecl());
- assert(FD->getBody());
- if (const CompoundStmt *S = dyn_cast<CompoundStmt>(FD->getBody()))
+void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args,
+ const Stmt *Body) {
+ if (const CompoundStmt *S = dyn_cast<CompoundStmt>(Body))
EmitCompoundStmtWithoutScope(*S);
else
- EmitStmt(FD->getBody());
+ EmitStmt(Body);
}
/// Tries to mark the given function nounwind based on the
@@ -672,6 +671,17 @@ static void TryMarkNoThrow(llvm::Function *F) {
F->setDoesNotThrow();
}
+static void EmitSizedDeallocationFunction(CodeGenFunction &CGF,
+ const FunctionDecl *UnsizedDealloc) {
+ // This is a weak discardable definition of the sized deallocation function.
+ CGF.CurFn->setLinkage(llvm::Function::LinkOnceAnyLinkage);
+
+ // Call the unsized deallocation function and forward the first argument
+ // unchanged.
+ llvm::Constant *Unsized = CGF.CGM.GetAddrOfFunction(UnsizedDealloc);
+ CGF.Builder.CreateCall(Unsized, &*CGF.CurFn->arg_begin());
+}
+
void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
const CGFunctionInfo &FnInfo) {
const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
@@ -726,9 +736,15 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
// Implicit copy-assignment gets the same special treatment as implicit
// copy-constructors.
emitImplicitAssignmentOperatorBody(Args);
- }
- else
- EmitFunctionBody(Args);
+ } else if (Stmt *Body = FD->getBody()) {
+ EmitFunctionBody(Args, Body);
+ } else if (FunctionDecl *UnsizedDealloc =
+ FD->getCorrespondingUnsizedGlobalDeallocationFunction()) {
+ // Global sized deallocation functions get an implicit weak definition if
+ // they don't have an explicit definition.
+ EmitSizedDeallocationFunction(*this, UnsizedDealloc);
+ } else
+ llvm_unreachable("no definition for emitted function");
// C++11 [stmt.return]p2:
// Flowing off the end of a function [...] results in undefined behavior in
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index b07e903b49f..98c090fa149 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1136,7 +1136,7 @@ public:
void EmitConstructorBody(FunctionArgList &Args);
void EmitDestructorBody(FunctionArgList &Args);
void emitImplicitAssignmentOperatorBody(FunctionArgList &Args);
- void EmitFunctionBody(FunctionArgList &Args);
+ void EmitFunctionBody(FunctionArgList &Args, const Stmt *Body);
void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator,
CallArgList &CallArgs);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index d0f34dddca3..c34f8332699 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1406,6 +1406,12 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,
DeferredDeclsToEmit.push_back(DDI->second);
DeferredDecls.erase(DDI);
+ // Otherwise, if this is a sized deallocation function, emit a weak definition
+ // for it at the end of the translation unit.
+ } else if (D && cast<FunctionDecl>(D)
+ ->getCorrespondingUnsizedGlobalDeallocationFunction()) {
+ DeferredDeclsToEmit.push_back(GD);
+
// Otherwise, there are cases we have to worry about where we're
// using a declaration for which we must emit a definition but where
// we might not find a top-level definition:
OpenPOWER on IntegriCloud