summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Belevich <tra@google.com>2016-10-21 20:34:05 +0000
committerArtem Belevich <tra@google.com>2016-10-21 20:34:05 +0000
commit07db5cf6c8b97a8db168086da180141523ee52bc (patch)
treebe6a39314df8c35ef82a808d40d6f81f2fd41275
parentca656239eb54cadfcf0ae8035fffd0def3e685e4 (diff)
downloadbcm5719-llvm-07db5cf6c8b97a8db168086da180141523ee52bc.tar.gz
bcm5719-llvm-07db5cf6c8b97a8db168086da180141523ee52bc.zip
Declare H and H new/delete.
llvm-svn: 284879
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp55
-rw-r--r--clang/test/SemaCUDA/overloaded-delete.cu46
2 files changed, 78 insertions, 23 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 83474cb7f83..49e25de2ac9 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -2593,28 +2593,39 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
getLangOpts().CPlusPlus11 ? EST_BasicNoexcept : EST_DynamicNone;
}
- QualType FnType = Context.getFunctionType(Return, Params, EPI);
- FunctionDecl *Alloc =
- FunctionDecl::Create(Context, GlobalCtx, SourceLocation(),
- SourceLocation(), Name,
- FnType, /*TInfo=*/nullptr, SC_None, false, true);
- Alloc->setImplicit();
-
- // Implicit sized deallocation functions always have default visibility.
- Alloc->addAttr(VisibilityAttr::CreateImplicit(Context,
- VisibilityAttr::Default));
-
- llvm::SmallVector<ParmVarDecl*, 3> ParamDecls;
- for (QualType T : Params) {
- ParamDecls.push_back(
- ParmVarDecl::Create(Context, Alloc, SourceLocation(), SourceLocation(),
- nullptr, T, /*TInfo=*/nullptr, SC_None, nullptr));
- ParamDecls.back()->setImplicit();
- }
- Alloc->setParams(ParamDecls);
-
- Context.getTranslationUnitDecl()->addDecl(Alloc);
- IdResolver.tryAddTopLevelDecl(Alloc, Name);
+ auto CreateAllocationFunctionDecl = [&](Attr *ExtraAttr) {
+ QualType FnType = Context.getFunctionType(Return, Params, EPI);
+ FunctionDecl *Alloc = FunctionDecl::Create(
+ Context, GlobalCtx, SourceLocation(), SourceLocation(), Name,
+ FnType, /*TInfo=*/nullptr, SC_None, false, true);
+ Alloc->setImplicit();
+
+ // Implicit sized deallocation functions always have default visibility.
+ Alloc->addAttr(
+ VisibilityAttr::CreateImplicit(Context, VisibilityAttr::Default));
+
+ llvm::SmallVector<ParmVarDecl *, 3> ParamDecls;
+ for (QualType T : Params) {
+ ParamDecls.push_back(ParmVarDecl::Create(
+ Context, Alloc, SourceLocation(), SourceLocation(), nullptr, T,
+ /*TInfo=*/nullptr, SC_None, nullptr));
+ ParamDecls.back()->setImplicit();
+ }
+ Alloc->setParams(ParamDecls);
+ if (ExtraAttr)
+ Alloc->addAttr(ExtraAttr);
+ Context.getTranslationUnitDecl()->addDecl(Alloc);
+ IdResolver.tryAddTopLevelDecl(Alloc, Name);
+ };
+
+ if (!LangOpts.CUDA)
+ CreateAllocationFunctionDecl(nullptr);
+ else {
+ // Host and device get their own declaration so each can be
+ // defined or re-declared independently.
+ CreateAllocationFunctionDecl(CUDAHostAttr::CreateImplicit(Context));
+ CreateAllocationFunctionDecl(CUDADeviceAttr::CreateImplicit(Context));
+ }
}
FunctionDecl *Sema::FindUsualDeallocationFunction(SourceLocation StartLoc,
diff --git a/clang/test/SemaCUDA/overloaded-delete.cu b/clang/test/SemaCUDA/overloaded-delete.cu
index e582fedb0aa..95a93a7a545 100644
--- a/clang/test/SemaCUDA/overloaded-delete.cu
+++ b/clang/test/SemaCUDA/overloaded-delete.cu
@@ -16,10 +16,54 @@ __host__ __device__ void test(S* s) {
delete s;
}
+// Code should work with no explicit declarations/definitions of
+// allocator functions.
+__host__ __device__ void test_default_global_delete_hd(int *ptr) {
+ // Again, there should be no ambiguity between which operator delete we call.
+ ::delete ptr;
+}
+
+__device__ void test_default_global_delete(int *ptr) {
+ // Again, there should be no ambiguity between which operator delete we call.
+ ::delete ptr;
+}
+__host__ void test_default_global_delete(int *ptr) {
+ // Again, there should be no ambiguity between which operator delete we call.
+ ::delete ptr;
+}
+
+// It should work with only some of allocators (re-)declared.
+__device__ void operator delete(void *ptr);
+
+__host__ __device__ void test_partial_global_delete_hd(int *ptr) {
+ // Again, there should be no ambiguity between which operator delete we call.
+ ::delete ptr;
+}
+
+__device__ void test_partial_global_delete(int *ptr) {
+ // Again, there should be no ambiguity between which operator delete we call.
+ ::delete ptr;
+}
+__host__ void test_partial_global_delete(int *ptr) {
+ // Again, there should be no ambiguity between which operator delete we call.
+ ::delete ptr;
+}
+
+
+// We should be able to define both host and device variants.
__host__ void operator delete(void *ptr) {}
__device__ void operator delete(void *ptr) {}
-__host__ __device__ void test_global_delete(int *ptr) {
+__host__ __device__ void test_overloaded_global_delete_hd(int *ptr) {
+ // Again, there should be no ambiguity between which operator delete we call.
+ ::delete ptr;
+}
+
+__device__ void test_overloaded_global_delete(int *ptr) {
+ // Again, there should be no ambiguity between which operator delete we call.
+ ::delete ptr;
+}
+__host__ void test_overloaded_global_delete(int *ptr) {
// Again, there should be no ambiguity between which operator delete we call.
::delete ptr;
}
OpenPOWER on IntegriCloud