diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 32 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 6 |
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: |