소스 검색

[OpenCL] Deduce addr space for pointee of dependent types in instantiation.

Since pointee doesn't require context sensitive addr space deduction
it's easier to handle pointee of dependent types during templ
instantiation.

Differential Revision: https://reviews.llvm.org/D64400



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@366063 91177308-0d34-0410-b5e6-96231b3b80d8
Anastasia Stulova 6 년 전
부모
커밋
8f781eb49f
2개의 변경된 파일56개의 추가작업 그리고 0개의 파일을 삭제
  1. 17 0
      lib/Sema/TreeTransform.h
  2. 39 0
      test/SemaOpenCLCXX/address-space-deduction.cl

+ 17 - 0
lib/Sema/TreeTransform.h

@@ -4536,6 +4536,14 @@ QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
   return Result;
   return Result;
 }
 }
 
 
+/// Helper to deduce addr space of a pointee type in OpenCL mode.
+/// If the type is updated it will be overwritten in PointeeType param.
+static void deduceOpenCLPointeeAddrSpace(Sema &SemaRef, QualType &PointeeType) {
+  if (PointeeType.getAddressSpace() == LangAS::Default)
+    PointeeType = SemaRef.Context.getAddrSpaceQualType(PointeeType,
+                                                       LangAS::opencl_generic);
+}
+
 template<typename Derived>
 template<typename Derived>
 QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
 QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
                                                       PointerTypeLoc TL) {
                                                       PointerTypeLoc TL) {
@@ -4544,6 +4552,9 @@ QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
   if (PointeeType.isNull())
   if (PointeeType.isNull())
     return QualType();
     return QualType();
 
 
+  if (SemaRef.getLangOpts().OpenCL)
+    deduceOpenCLPointeeAddrSpace(SemaRef, PointeeType);
+
   QualType Result = TL.getType();
   QualType Result = TL.getType();
   if (PointeeType->getAs<ObjCObjectType>()) {
   if (PointeeType->getAs<ObjCObjectType>()) {
     // A dependent pointer type 'T *' has is being transformed such
     // A dependent pointer type 'T *' has is being transformed such
@@ -4582,6 +4593,9 @@ TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
   if (PointeeType.isNull())
   if (PointeeType.isNull())
     return QualType();
     return QualType();
 
 
+  if (SemaRef.getLangOpts().OpenCL)
+    deduceOpenCLPointeeAddrSpace(SemaRef, PointeeType);
+
   QualType Result = TL.getType();
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
   if (getDerived().AlwaysRebuild() ||
       PointeeType != TL.getPointeeLoc().getType()) {
       PointeeType != TL.getPointeeLoc().getType()) {
@@ -4611,6 +4625,9 @@ TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
   if (PointeeType.isNull())
   if (PointeeType.isNull())
     return QualType();
     return QualType();
 
 
+  if (SemaRef.getLangOpts().OpenCL)
+    deduceOpenCLPointeeAddrSpace(SemaRef, PointeeType);
+
   QualType Result = TL.getType();
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
   if (getDerived().AlwaysRebuild() ||
       PointeeType != T->getPointeeTypeAsWritten()) {
       PointeeType != T->getPointeeTypeAsWritten()) {

+ 39 - 0
test/SemaOpenCLCXX/address-space-deduction.cl

@@ -24,3 +24,42 @@ struct c2 {
   alias_c1_ptr ptr = &y;
   alias_c1_ptr ptr = &y;
 };
 };
 
 
+
+// Addr spaces for pointee of dependent types are not deduced
+// during parsing but during template instantiation instead.
+
+template <class T>
+struct x1 {
+//CHECK: -CXXMethodDecl {{.*}} operator= 'x1<T> &(const x1<T> &) __generic'
+//CHECK: -CXXMethodDecl {{.*}} operator= '__generic x1<int> &(const __generic x1<int> &) __generic'
+  x1<T>& operator=(const x1<T>& xx) {
+    y = xx.y;
+    return *this;
+  }
+  int y;
+};
+
+template <class T>
+struct x2 {
+//CHECK: -CXXMethodDecl {{.*}} foo 'void (x1<T> *) __generic'
+//CHECK: -CXXMethodDecl {{.*}} foo 'void (__generic x1<int> *) __generic'
+  void foo(x1<T>* xx) {
+    m[0] = *xx;
+  }
+//CHECK: -FieldDecl {{.*}}  m 'x1<int> [2]'
+  x1<T> m[2];
+};
+
+void bar(__global x1<int> *xx, __global x2<int> *bar) {
+  bar->foo(xx);
+}
+
+template <typename T>
+class x3 : public T {
+public:
+  //CHECK: -CXXConstructorDecl {{.*}} x3<T> 'void (const x3<T> &) __generic'
+  x3(const x3 &t);
+};
+//CHECK: -CXXConstructorDecl {{.*}} x3<T> 'void (const x3<T> &) __generic'
+template <typename T>
+x3<T>::x3(const x3<T> &t) {}