olestrohm updated this revision to Diff 373225.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D109609/new/

https://reviews.llvm.org/D109609

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/DeclCXX.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaLookup.cpp
  clang/test/SemaOpenCLCXX/addrspace-destructors.clcpp

Index: clang/test/SemaOpenCLCXX/addrspace-destructors.clcpp
===================================================================
--- /dev/null
+++ clang/test/SemaOpenCLCXX/addrspace-destructors.clcpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 %s -pedantic -ast-dump | FileCheck %s
+
+// CHECK: CXXDestructorDecl {{.*}} used ~ExactDtor 'void () __private noexcept'
+struct ExactDtor {
+     ~ExactDtor() __private;
+};
+
+// CHECK: CXXDestructorDecl
+// CHECK-NOT: used
+// CHECK-SAME: ~OverloadedDtor 'void () __generic'
+// CHECK: CXXDestructorDecl {{.*}} used ~OverloadedDtor 'void () __private noexcept'
+struct OverloadedDtor {
+     ~OverloadedDtor() __generic;
+     ~OverloadedDtor() __private;
+};
+
+// CHECK: CXXDestructorDecl
+// CHECK-NOT: used
+// CHECK-SAME: ~ImplicitDtor 'void () __global'
+// CHECK: CXXDestructorDecl {{.*}} implicit used ~ImplicitDtor 'void () __generic noexcept'
+struct ImplicitDtor {
+    ~ImplicitDtor() __global;
+};
+
+// CHECK: CXXDestructorDecl {{.*}} used ~Templated 'void () __generic noexcept'
+// CHECK: CXXDestructorDecl
+// CHECK-NOT: used
+// CHECK-SAME: ~Templated 'void () __global'
+template <typename T>
+struct Templated {
+    ~Templated() __generic;
+    ~Templated() __global;
+};
+
+// CHECK: CXXDestructorDecl {{.*}} used ~BothUsed 'void () __private noexcept'
+// CHECK: CXXDestructorDecl {{.*}} used ~BothUsed 'void () __global noexcept'
+struct BothUsed {
+    ~BothUsed() __private;
+    ~BothUsed() __global;
+};
+
+__global BothUsed g_inheriting;
+
+kernel void k() {
+    __private ExactDtor exact;
+    __private OverloadedDtor overloaded;
+    __private ImplicitDtor implicit;
+    __private Templated<int> templated;
+    __private BothUsed inheriting;
+}
Index: clang/lib/Sema/SemaLookup.cpp
===================================================================
--- clang/lib/Sema/SemaLookup.cpp
+++ clang/lib/Sema/SemaLookup.cpp
@@ -3054,13 +3054,10 @@
   Functions.append(Operators.begin(), Operators.end());
 }
 
-Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD,
-                                                           CXXSpecialMember SM,
-                                                           bool ConstArg,
-                                                           bool VolatileArg,
-                                                           bool RValueThis,
-                                                           bool ConstThis,
-                                                           bool VolatileThis) {
+Sema::SpecialMemberOverloadResult
+Sema::LookupSpecialMember(CXXRecordDecl *RD, CXXSpecialMember SM, bool ConstArg,
+                          bool VolatileArg, bool RValueThis, bool ConstThis,
+                          bool VolatileThis, LangAS ASThis) {
   assert(CanDeclareSpecialMemberFunction(RD) &&
          "doing special member lookup into record that isn't fully complete");
   RD = RD->getDefinition();
@@ -3082,6 +3079,7 @@
   ID.AddInteger(RValueThis);
   ID.AddInteger(ConstThis);
   ID.AddInteger(VolatileThis);
+  ID.AddInteger((unsigned)ASThis);
 
   void *InsertPoint;
   SpecialMemberOverloadResultEntry *Result =
@@ -3096,12 +3094,12 @@
   SpecialMemberCache.InsertNode(Result, InsertPoint);
 
   if (SM == CXXDestructor) {
-    if (RD->needsImplicitDestructor()) {
+    if (RD->needsImplicitDestructor(ASThis)) {
       runWithSufficientStackSpace(RD->getLocation(), [&] {
         DeclareImplicitDestructor(RD);
       });
     }
-    CXXDestructorDecl *DD = RD->getDestructor();
+    CXXDestructorDecl *DD = RD->getDestructor(ASThis);
     Result->setMethod(DD);
     Result->setKind(DD && !DD->isDeleted()
                         ? SpecialMemberOverloadResult::Success
@@ -3362,10 +3360,11 @@
 /// CXXRecordDecl::getDestructor().
 ///
 /// \returns The destructor for this class.
-CXXDestructorDecl *Sema::LookupDestructor(CXXRecordDecl *Class) {
+CXXDestructorDecl *Sema::LookupDestructor(CXXRecordDecl *Class, LangAS AS) {
   return cast<CXXDestructorDecl>(LookupSpecialMember(Class, CXXDestructor,
-                                                     false, false, false,
-                                                     false, false).getMethod());
+                                                     false, false, false, false,
+                                                     false, AS)
+                                     .getMethod());
 }
 
 /// LookupLiteralOperator - Determine which literal operator should be used for
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -13529,7 +13529,7 @@
   //   If a class has no user-declared destructor, a destructor is
   //   declared implicitly. An implicitly-declared destructor is an
   //   inline public member of its class.
-  assert(ClassDecl->needsImplicitDestructor());
+  assert(ClassDecl->needsImplicitDestructor(getDefaultCXXMethodAddrSpace()));
 
   DeclaringSpecialMember DSM(*this, ClassDecl, CXXDestructor);
   if (DSM.isAlreadyBeingDeclared())
@@ -15451,7 +15451,11 @@
   if (VD->isNoDestroy(getASTContext()))
     return;
 
-  CXXDestructorDecl *Destructor = LookupDestructor(ClassDecl);
+  LangAS AS = LangAS::Default;
+  if (Context.getLangOpts().OpenCL) {
+    AS = VD->getType().getAddressSpace();
+  }
+  CXXDestructorDecl *Destructor = LookupDestructor(ClassDecl, AS);
 
   // If this is an array, we'll require the destructor during initialization, so
   // we can skip over this. We still want to emit exit-time destructor warnings
Index: clang/lib/AST/DeclCXX.cpp
===================================================================
--- clang/lib/AST/DeclCXX.cpp
+++ clang/lib/AST/DeclCXX.cpp
@@ -1884,7 +1884,7 @@
   return nullptr;
 }
 
-CXXDestructorDecl *CXXRecordDecl::getDestructor() const {
+CXXDestructorDecl *CXXRecordDecl::getDestructor(LangAS AS) const {
   ASTContext &Context = getASTContext();
   QualType ClassType = Context.getTypeDeclType(this);
 
@@ -1894,7 +1894,24 @@
 
   DeclContext::lookup_result R = lookup(Name);
 
-  return R.empty() ? nullptr : dyn_cast<CXXDestructorDecl>(R.front());
+  if (AS == LangAS::Default)
+    return R.empty() ? nullptr : dyn_cast<CXXDestructorDecl>(R.front());
+
+  CXXDestructorDecl *Best = nullptr;
+
+  for (DeclContext::lookup_result::iterator I = R.begin(), E = R.end(); I != E;
+       ++I) {
+    auto *Dtor = dyn_cast<CXXDestructorDecl>(*I);
+    LangAS DtorAS = Dtor->getMethodQualifiers().getAddressSpace();
+    if (Qualifiers::isAddressSpaceSupersetOf(DtorAS, AS) &&
+        (Best == nullptr ||
+         Qualifiers::isAddressSpaceSupersetOf(
+             Best->getMethodQualifiers().getAddressSpace(), DtorAS))) {
+      Best = Dtor;
+    }
+  }
+
+  return Best;
 }
 
 static bool isDeclContextInNamespace(const DeclContext *DC) {
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -4042,13 +4042,10 @@
     LOLR_StringTemplatePack,
   };
 
-  SpecialMemberOverloadResult LookupSpecialMember(CXXRecordDecl *D,
-                                                  CXXSpecialMember SM,
-                                                  bool ConstArg,
-                                                  bool VolatileArg,
-                                                  bool RValueThis,
-                                                  bool ConstThis,
-                                                  bool VolatileThis);
+  SpecialMemberOverloadResult
+  LookupSpecialMember(CXXRecordDecl *D, CXXSpecialMember SM, bool ConstArg,
+                      bool VolatileArg, bool RValueThis, bool ConstThis,
+                      bool VolatileThis, LangAS ASThis = LangAS::Default);
 
   typedef std::function<void(const TypoCorrection &)> TypoDiagnosticGenerator;
   typedef std::function<ExprResult(Sema &, TypoExpr *, TypoCorrection)>
@@ -4144,7 +4141,8 @@
                                               unsigned Quals);
   CXXMethodDecl *LookupMovingAssignment(CXXRecordDecl *Class, unsigned Quals,
                                         bool RValueThis, unsigned ThisQuals);
-  CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);
+  CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class,
+                                      LangAS AS = LangAS::Default);
 
   bool checkLiteralOperatorId(const CXXScopeSpec &SS, const UnqualifiedId &Id,
                               bool IsUDSuffix);
Index: clang/include/clang/AST/DeclCXX.h
===================================================================
--- clang/include/clang/AST/DeclCXX.h
+++ clang/include/clang/AST/DeclCXX.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_AST_DECLCXX_H
 #define LLVM_CLANG_AST_DECLCXX_H
 
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTUnresolvedSet.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
@@ -978,7 +979,11 @@
 
   /// Determine whether this class needs an implicit destructor to
   /// be lazily declared.
-  bool needsImplicitDestructor() const {
+  bool needsImplicitDestructor(LangAS AS = LangAS::Default) const {
+    if (getASTContext().getLangOpts().OpenCL) {
+      return getDestructor(AS) == nullptr;
+    }
+
     return !(data().DeclaredSpecialMembers & SMF_Destructor);
   }
 
@@ -1476,7 +1481,7 @@
   }
 
   /// Returns the destructor decl for this class.
-  CXXDestructorDecl *getDestructor() const;
+  CXXDestructorDecl *getDestructor(LangAS AS = LangAS::Default) const;
 
   /// Returns true if the class destructor, or any implicitly invoked
   /// destructors are marked noreturn.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to