Anastasia updated this revision to Diff 208993. Anastasia marked 2 inline comments as done. Anastasia added a comment.
- Added handling of similar test case with `InjectedClassNameType` CHANGES SINCE LAST ACTION https://reviews.llvm.org/D64400/new/ https://reviews.llvm.org/D64400 Files: include/clang/AST/Type.h lib/Sema/SemaType.cpp test/SemaOpenCLCXX/address-space-deduction.cl Index: test/SemaOpenCLCXX/address-space-deduction.cl =================================================================== --- test/SemaOpenCLCXX/address-space-deduction.cl +++ test/SemaOpenCLCXX/address-space-deduction.cl @@ -38,3 +38,41 @@ int foo[10]; xxx(&foo[0]); } + +// Deducing addr spaces for template specialization is fine +// addr space of template arg can't affecting the addr space +// of specialization + +template <class T> +struct x1 { +//CHECK: -CXXMethodDecl {{.*}} operator= '__generic x1<T> &(const __generic x1<T> &) __generic' + x1<T>& operator=(const x1<T>& xx) { + y = xx.y; + return *this; + } + int y; +}; + +template <class T> +struct x2 { +//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 __generic x3<T> &) __generic' + x3(const x3 &t); +}; +//CHECK: -CXXConstructorDecl {{.*}} 'void (const __generic x3<T> &) __generic' +template <typename T> +x3<T>::x3(const x3<T> &t) {} Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -7414,9 +7414,14 @@ (T->isVoidType() && !IsPointee) || // Do not deduce addr spaces for dependent types because they might end // up instantiating to a type with an explicit address space qualifier. - // Expect for pointer or reference types because the addr space in - // template argument can only belong to a pointee. - (T->isDependentType() && !T->isPointerType() && !T->isReferenceType()) || + // Except for: + // - pointer or reference types because the addr space in template + // argument can only belong to a pointee. + // - template specialization as addr space in template argument doesn't + // affect specialization. + (T->isDependentType() && + (!T->isPointerType() && !T->isReferenceType() && + !T->isTemplateSpecializationType() && !T->isInjectedClassNameType())) || // Do not deduce addr space of decltype because it will be taken from // its argument. T->isDecltypeType() || Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -1981,6 +1981,8 @@ bool isObjCBoxableRecordType() const; bool isInterfaceType() const; bool isStructureOrClassType() const; + bool isTemplateSpecializationType() const; + bool isInjectedClassNameType() const; bool isUnionType() const; bool isComplexIntegerType() const; // GCC _Complex integer type. bool isVectorType() const; // GCC vector type. @@ -6507,6 +6509,14 @@ return isa<DecltypeType>(this); } +inline bool Type::isTemplateSpecializationType() const { + return isa<TemplateSpecializationType>(this); +} + +inline bool Type::isInjectedClassNameType() const { + return isa<InjectedClassNameType>(this); +} + #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ inline bool Type::is##Id##Type() const { \ return isSpecificBuiltinType(BuiltinType::Id); \
Index: test/SemaOpenCLCXX/address-space-deduction.cl =================================================================== --- test/SemaOpenCLCXX/address-space-deduction.cl +++ test/SemaOpenCLCXX/address-space-deduction.cl @@ -38,3 +38,41 @@ int foo[10]; xxx(&foo[0]); } + +// Deducing addr spaces for template specialization is fine +// addr space of template arg can't affecting the addr space +// of specialization + +template <class T> +struct x1 { +//CHECK: -CXXMethodDecl {{.*}} operator= '__generic x1<T> &(const __generic x1<T> &) __generic' + x1<T>& operator=(const x1<T>& xx) { + y = xx.y; + return *this; + } + int y; +}; + +template <class T> +struct x2 { +//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 __generic x3<T> &) __generic' + x3(const x3 &t); +}; +//CHECK: -CXXConstructorDecl {{.*}} 'void (const __generic x3<T> &) __generic' +template <typename T> +x3<T>::x3(const x3<T> &t) {} Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -7414,9 +7414,14 @@ (T->isVoidType() && !IsPointee) || // Do not deduce addr spaces for dependent types because they might end // up instantiating to a type with an explicit address space qualifier. - // Expect for pointer or reference types because the addr space in - // template argument can only belong to a pointee. - (T->isDependentType() && !T->isPointerType() && !T->isReferenceType()) || + // Except for: + // - pointer or reference types because the addr space in template + // argument can only belong to a pointee. + // - template specialization as addr space in template argument doesn't + // affect specialization. + (T->isDependentType() && + (!T->isPointerType() && !T->isReferenceType() && + !T->isTemplateSpecializationType() && !T->isInjectedClassNameType())) || // Do not deduce addr space of decltype because it will be taken from // its argument. T->isDecltypeType() || Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -1981,6 +1981,8 @@ bool isObjCBoxableRecordType() const; bool isInterfaceType() const; bool isStructureOrClassType() const; + bool isTemplateSpecializationType() const; + bool isInjectedClassNameType() const; bool isUnionType() const; bool isComplexIntegerType() const; // GCC _Complex integer type. bool isVectorType() const; // GCC vector type. @@ -6507,6 +6509,14 @@ return isa<DecltypeType>(this); } +inline bool Type::isTemplateSpecializationType() const { + return isa<TemplateSpecializationType>(this); +} + +inline bool Type::isInjectedClassNameType() const { + return isa<InjectedClassNameType>(this); +} + #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ inline bool Type::is##Id##Type() const { \ return isSpecificBuiltinType(BuiltinType::Id); \
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits