aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-06-03 23:27:44 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-06-03 23:27:44 +0000
commit760520bcb78d9b91b3bbf74704d9cb3ba6b5c5b6 (patch)
tree1ff10bb9dab6817ca90dcf831870df27b85a0389 /clang/lib
parent08d84943afdce3e73c256e273d2697002303f9f7 (diff)
downloadllvm-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.cpp6
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp17
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h6
-rw-r--r--clang/lib/Sema/SemaChecking.cpp16
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) {