//RUN: %clang_cc1 %s -pedantic -ast-dump -verify | FileCheck %s //expected-no-diagnostics //CHECK: |-VarDecl {{.*}} foo 'const __global int' constexpr int foo = 0; //CHECK: |-VarDecl {{.*}} foo1 'T' cinit //CHECK: `-VarTemplateSpecializationDecl {{.*}} used foo1 '__global long':'__global long' cinit template <typename T> T foo1 = 0; class c { public: //CHECK: `-VarDecl {{.*}} foo2 'const __global int' static constexpr int foo2 = 0; }; struct c1 {}; // We only deduce addr space in type alias in pointer types. //CHECK: TypeAliasDecl {{.*}} alias_c1 'c1' using alias_c1 = c1; //CHECK: TypeAliasDecl {{.*}} alias_c1_ptr '__generic c1 *' using alias_c1_ptr = c1 *; struct c2 { alias_c1 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> &){{( __attribute__.*)?}} __generic' //CHECK: -CXXMethodDecl {{.*}} operator= '__generic x1<int> &(const __generic x1<int> &__private){{( __attribute__.*)?}} __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> *){{( __attribute__.*)?}} __generic' //CHECK: -CXXMethodDecl {{.*}} foo 'void (__generic x1<int> *__private){{( __attribute__.*)?}} __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> &){{( __attribute__.*)?}} __generic' x3(const x3 &t); }; //CHECK: -CXXConstructorDecl {{.*}} x3<T> 'void (const x3<T> &){{( __attribute__.*)?}} __generic' template <typename T> x3<T>::x3(const x3<T> &t) {} template <class T> T xxx(T *in1, T in2) { // This pointer can't be deduced to generic because addr space // will be taken from the template argument. //CHECK: `-VarDecl {{.*}} 'T *' cinit //CHECK: `-VarDecl {{.*}} i '__private int *__private' cinit T *i = in1; T ii; __private T *ptr = ⅈ ptr = &in2; return *i; } __kernel void test() { int foo[10]; xxx<__private int>(&foo[0], foo[0]); // FIXME: Template param deduction fails here because // temporaries are not in the __private address space. // It is probably reasonable to put them in __private // considering that stack and function params are // implicitly in __private. // However, if temporaries are left in default addr // space we should at least pretty print the __private // addr space. Otherwise diagnostic apprears to be // confusing. //xxx(&foo[0], foo[0]); } // Addr space for pointer/reference to an array //CHECK: FunctionDecl {{.*}} t1 'void (const float (__generic &__private)[2])' void t1(const float (&fYZ)[2]); //CHECK: FunctionDecl {{.*}} t2 'void (const float (__generic *__private)[2])' void t2(const float (*fYZ)[2]); //CHECK: FunctionDecl {{.*}} t3 'void (float (((__generic *__private)))[2])' void t3(float(((*fYZ)))[2]); //CHECK: FunctionDecl {{.*}} t4 'void (float (((__generic *__generic *__private)))[2])' void t4(float(((**fYZ)))[2]); //CHECK: FunctionDecl {{.*}} t5 'void (float (__generic *(__generic *__private))[2])' void t5(float (*(*fYZ))[2]); __kernel void k() { __local float x[2]; float(*p)[2]; t1(x); t2(&x); t3(&x); t4(&p); t5(&p); long f1 = foo1<long>; }