diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-06-03 23:27:44 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-06-03 23:27:44 +0000 |
commit | 760520bcb78d9b91b3bbf74704d9cb3ba6b5c5b6 (patch) | |
tree | 1ff10bb9dab6817ca90dcf831870df27b85a0389 /clang/lib | |
parent | 08d84943afdce3e73c256e273d2697002303f9f7 (diff) | |
download | llvm-760520bcb78d9b91b3bbf74704d9cb3ba6b5c5b6.zip llvm-760520bcb78d9b91b3bbf74704d9cb3ba6b5c5b6.tar.gz llvm-760520bcb78d9b91b3bbf74704d9cb3ba6b5c5b6.tar.bz2 |
Add __builtin_operator_new and __builtin_operator_delete, which act like calls
to the normal non-placement ::operator new and ::operator delete, but allow
optimizations like new-expressions and delete-expressions do.
llvm-svn: 210137
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 17 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 16 |
4 files changed, 43 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 8b62ef0..f705ed8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1508,6 +1508,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, } case Builtin::BI__builtin_addressof: return RValue::get(EmitLValue(E->getArg(0)).getAddress()); + case Builtin::BI__builtin_operator_new: + return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(), + E->getArg(0), false); + case Builtin::BI__builtin_operator_delete: + return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(), + E->getArg(0), true); case Builtin::BI__noop: return RValue::get(nullptr); case Builtin::BI_InterlockedCompareExchange: { diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 762d8e2..0492813 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -1029,6 +1029,23 @@ static RValue EmitNewDeleteCall(CodeGenFunction &CGF, return RV; } +RValue CodeGenFunction::EmitBuiltinNewDeleteCall(const FunctionProtoType *Type, + const Expr *Arg, + bool IsDelete) { + CallArgList Args; + const Stmt *ArgS = Arg; + EmitCallArgs(Args, *Type->param_type_begin(), + ConstExprIterator(&ArgS), ConstExprIterator(&ArgS + 1)); + // Find the allocation or deallocation function that we're calling. + ASTContext &Ctx = getContext(); + DeclarationName Name = Ctx.DeclarationNames + .getCXXOperatorName(IsDelete ? OO_Delete : OO_New); + for (auto *Decl : Ctx.getTranslationUnitDecl()->lookup(Name)) + if (Ctx.hasSameType(cast<FunctionDecl>(Decl)->getType(), QualType(Type, 0))) + return EmitNewDeleteCall(*this, cast<FunctionDecl>(Decl), Type, Args); + llvm_unreachable("predeclared global operator new/delete is missing"); +} + namespace { /// A cleanup to call the given 'operator delete' function upon /// abnormal exit from a new expression. diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index d1e63a7..b6c58e0 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1659,6 +1659,9 @@ public: void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy); + RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type, + const Expr *Arg, bool IsDelete); + llvm::Value* EmitCXXTypeidExpr(const CXXTypeidExpr *E); llvm::Value *EmitDynamicCast(llvm::Value *V, const CXXDynamicCastExpr *DCE); llvm::Value* EmitCXXUuidofExpr(const CXXUuidofExpr *E); @@ -2641,7 +2644,8 @@ public: void EmitCallArgs(CallArgList &Args, ArrayRef<QualType> ArgTypes, CallExpr::const_arg_iterator ArgBeg, - CallExpr::const_arg_iterator ArgEnd, bool ForceColumnInfo); + CallExpr::const_arg_iterator ArgEnd, + bool ForceColumnInfo = false); private: const TargetCodeGenInfo &getTargetHooks() const { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 60514ef..916ce7d 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -296,8 +296,22 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (SemaBuiltinAddressof(*this, TheCall)) return ExprError(); break; + case Builtin::BI__builtin_operator_new: + case Builtin::BI__builtin_operator_delete: + if (!getLangOpts().CPlusPlus) { + Diag(TheCall->getExprLoc(), diag::err_builtin_requires_language) + << (BuiltinID == Builtin::BI__builtin_operator_new + ? "__builtin_operator_new" + : "__builtin_operator_delete") + << "C++"; + return ExprError(); + } + // CodeGen assumes it can find the global new and delete to call, + // so ensure that they are declared. + DeclareGlobalNewDelete(); + break; } - + // Since the target specific builtins for each arch overlap, only check those // of the arch we are compiling for. if (BuiltinID >= Builtin::FirstTSBuiltin) { |