Index: include/clang/Basic/AddressSpaces.h =================================================================== --- include/clang/Basic/AddressSpaces.h +++ include/clang/Basic/AddressSpaces.h @@ -35,6 +35,7 @@ opencl_global, opencl_local, opencl_constant, + opencl_private, opencl_generic, // CUDA specific address spaces. Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -707,6 +707,7 @@ 1, // opencl_global 3, // opencl_local 2, // opencl_constant + 0, // opencl_private 4, // opencl_generic 5, // cuda_device 6, // cuda_constant Index: lib/AST/ItaniumMangle.cpp =================================================================== --- lib/AST/ItaniumMangle.cpp +++ lib/AST/ItaniumMangle.cpp @@ -2155,15 +2155,17 @@ if (Context.getASTContext().addressSpaceMapManglingFor(AS)) { // ::= "AS" unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS); - ASString = "AS" + llvm::utostr(TargetAS); + if (TargetAS != 0) + ASString = "AS" + llvm::utostr(TargetAS); } else { switch (AS) { default: llvm_unreachable("Not a language specific address space"); - // ::= "CL" [ "global" | "local" | "constant | - // "generic" ] + // ::= "CL" [ "global" | "local" | "constant" | + // "private"| "generic" ] case LangAS::opencl_global: ASString = "CLglobal"; break; case LangAS::opencl_local: ASString = "CLlocal"; break; case LangAS::opencl_constant: ASString = "CLconstant"; break; + case LangAS::opencl_private: ASString = "CLprivate"; break; case LangAS::opencl_generic: ASString = "CLgeneric"; break; // ::= "CU" [ "device" | "constant" | "shared" ] case LangAS::cuda_device: ASString = "CUdevice"; break; @@ -2171,7 +2173,8 @@ case LangAS::cuda_shared: ASString = "CUshared"; break; } } - mangleVendorQualifier(ASString); + if (!ASString.empty()) + mangleVendorQualifier(ASString); } // The ARC ownership qualifiers start with underscores. Index: lib/AST/TypePrinter.cpp =================================================================== --- lib/AST/TypePrinter.cpp +++ lib/AST/TypePrinter.cpp @@ -1658,6 +1658,9 @@ case LangAS::cuda_constant: OS << "__constant"; break; + case LangAS::opencl_private: + OS << "__private"; + break; case LangAS::opencl_generic: OS << "__generic"; break; Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -1799,6 +1799,7 @@ 1, // opencl_global 3, // opencl_local 4, // opencl_constant + 0, // opencl_private // FIXME: generic has to be added to the target 0, // opencl_generic 1, // cuda_device @@ -2054,6 +2055,7 @@ 1, // opencl_global 3, // opencl_local 2, // opencl_constant + 0, // opencl_private 4, // opencl_generic 1, // cuda_device 2, // cuda_constant @@ -2064,6 +2066,7 @@ 1, // opencl_global 3, // opencl_local 2, // opencl_constant + 5, // opencl_private 0, // opencl_generic 1, // cuda_device 2, // cuda_constant @@ -2074,6 +2077,7 @@ 1, // opencl_global 3, // opencl_local 2, // opencl_constant + 0, // opencl_private 4, // opencl_generic 1, // cuda_device 2, // cuda_constant @@ -2084,6 +2088,7 @@ 1, // opencl_global 3, // opencl_local 2, // opencl_constant + 5, // opencl_private 0, // opencl_generic 1, // cuda_device 2, // cuda_constant @@ -7703,6 +7708,7 @@ 3, // opencl_global 4, // opencl_local 5, // opencl_constant + 0, // opencl_private // FIXME: generic has to be added to the target 0, // opencl_generic 0, // cuda_device @@ -8827,6 +8833,7 @@ 1, // opencl_global 3, // opencl_local 2, // opencl_constant + 0, // opencl_private 4, // opencl_generic 0, // cuda_device 0, // cuda_constant Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -721,6 +721,9 @@ case Builtin::BIto_local: Qual.setAddressSpace(LangAS::opencl_local); break; + case Builtin::BIto_private: + Qual.setAddressSpace(LangAS::opencl_private); + break; default: Qual.removeAddressSpace(); } Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -7325,7 +7325,7 @@ return; } } - } else if (T.getAddressSpace() != LangAS::Default) { + } else if (T.getAddressSpace() != LangAS::opencl_private) { // Do not allow other address spaces on automatic variable. Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl) << 1; NewVD->setInvalidDecl(); @@ -7960,6 +7960,7 @@ if (PointeeType->isPointerType()) return PtrPtrKernelParam; if (PointeeType.getAddressSpace() == LangAS::opencl_generic || + PointeeType.getAddressSpace() == LangAS::opencl_private || PointeeType.getAddressSpace() == 0) return InvalidAddrSpacePtrKernelParam; return PtrKernelParam; Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -5566,7 +5566,7 @@ ASIdx = LangAS::opencl_generic; break; default: assert(Attr.getKind() == AttributeList::AT_OpenCLPrivateAddressSpace); - ASIdx = 0; break; + ASIdx = LangAS::opencl_private; break; } } @@ -6966,6 +6966,33 @@ } } + // OpenCL v1.2 s6.5: + // The generic address space name for arguments to a function in a program, + // or local variables of a function is __private. All function arguments + // shall be in the __private address space. + if (state.getSema().getLangOpts().OpenCL && + state.getSema().getLangOpts().OpenCLVersion <= 120 && + !hasOpenCLAddressSpace && type.getAddressSpace() == 0 && + (TAL == TAL_DeclSpec || TAL == TAL_DeclChunk)) { + Declarator &D = state.getDeclarator(); + if (state.getCurrentChunkIndex() == 0 && !D.isFunctionDeclarator() && + !D.isFunctionDefinition() && + D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef && + !type->isSamplerT()) { + if (D.getContext() == Declarator::BlockContext) { + if (D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static) { + type = state.getSema().Context.getAddrSpaceQualType( + type, LangAS::opencl_private); + } + } + } else if (state.getCurrentChunkIndex() > 0 && + (D.getTypeObject(state.getCurrentChunkIndex() - 1).Kind == + DeclaratorChunk::Pointer)) { + type = state.getSema().Context.getAddrSpaceQualType( + type, LangAS::opencl_private); + } + } + // If address space is not set, OpenCL 2.0 defines non private default // address spaces for some cases: // OpenCL 2.0, section 6.5: @@ -6987,15 +7014,24 @@ type = state.getSema().Context.getAddrSpaceQualType( type, LangAS::opencl_generic); } else if (state.getCurrentChunkIndex() == 0 && - D.getContext() == Declarator::FileContext && !D.isFunctionDeclarator() && !D.isFunctionDefinition() && D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef && - !type->isSamplerT()) - type = state.getSema().Context.getAddrSpaceQualType( + !type->isSamplerT()) { + if (D.getContext() == Declarator::FileContext) { + type = state.getSema().Context.getAddrSpaceQualType( type, LangAS::opencl_global); - else if (state.getCurrentChunkIndex() == 0 && - D.getContext() == Declarator::BlockContext && - D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static) + } else if (D.getContext() == Declarator::BlockContext) { + if (D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static) { + type = state.getSema().Context.getAddrSpaceQualType( + type, LangAS::opencl_private); + } else { + type = state.getSema().Context.getAddrSpaceQualType( + type, LangAS::opencl_global); + } + } + } else if (state.getCurrentChunkIndex() == 0 && + D.getContext() == Declarator::BlockContext && + D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static) type = state.getSema().Context.getAddrSpaceQualType( type, LangAS::opencl_global); } Index: test/CodeGenOpenCL/address-spaces-mangling.cl =================================================================== --- test/CodeGenOpenCL/address-spaces-mangling.cl +++ test/CodeGenOpenCL/address-spaces-mangling.cl @@ -1,5 +1,7 @@ -// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefix=ASMANG %s -// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefix=NOASMANG %s +// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes=ASMANG,ASMAN10 %s +// RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes=ASMANG,ASMAN20 %s +// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes=NOASMANG,NOASMAN10 %s +// RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes=NOASMANG,NOASMAN20 %s // We check that the address spaces are mangled the same in both version of OpenCL // RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL2.0 -emit-llvm -o - | FileCheck -check-prefix=OCL-20 %s @@ -10,15 +12,17 @@ // warnings, but we do want it for comparison purposes. __attribute__((overloadable)) void ff(int *arg) { } -// ASMANG: @_Z2ffPi -// NOASMANG: @_Z2ffPi +// ASMANG10: @_Z2ffPi +// ASMANG20: @_Z2ffPU3AS4i +// NOASMANG10: @_Z2ffPi +// NOASMANG20: @_Z2ffPU9CLgenerici // OCL-20-DAG: @_Z2ffPU3AS4i // OCL-12-DAG: @_Z2ffPi __attribute__((overloadable)) void f(private int *arg) { } // ASMANG: @_Z1fPi -// NOASMANG: @_Z1fPi +// NOASMANG: @_Z1fPU9CLprivatei // OCL-20-DAG: @_Z1fPi // OCL-12-DAG: @_Z1fPi @@ -42,3 +46,11 @@ // NOASMANG: @_Z1fPU10CLconstanti // OCL-20-DAG: @_Z1fPU3AS2i // OCL-12-DAG: @_Z1fPU3AS2i + +#if __OPENCL_C_VERSION__ >= 200 +__attribute__((overloadable)) +void f(generic int *arg) { } +// ASMANG20: @_Z1fPU3AS4i +// NOASMANG20: @_Z1fPU9CLgenerici +// OCL-20-DAG: @_Z1fPU3AS4i +#endif Index: test/SemaOpenCL/address-spaces-conversions-cl2.0.cl =================================================================== --- test/SemaOpenCL/address-spaces-conversions-cl2.0.cl +++ test/SemaOpenCL/address-spaces-conversions-cl2.0.cl @@ -76,7 +76,7 @@ AS int *var_init4 = arg_priv; #ifndef GENERIC -// expected-error-re@-2{{initializing '__{{global|constant}} int *' with an expression of type 'int *' changes address space of pointer}} +// expected-error-re@-2{{initializing '__{{global|constant}} int *' with an expression of type '__private int *' changes address space of pointer}} #endif AS int *var_init5 = arg_gen; @@ -101,7 +101,7 @@ AS int *var_cast4 = (AS int *)arg_priv; #ifndef GENERIC -// expected-error-re@-2{{casting 'int *' to type '__{{global|constant}} int *' changes address space of pointer}} +// expected-error-re@-2{{casting '__private int *' to type '__{{global|constant}} int *' changes address space of pointer}} #endif AS int *var_cast5 = (AS int *)arg_gen; @@ -127,7 +127,7 @@ var_impl = arg_priv; #ifndef GENERIC -// expected-error-re@-2{{assigning 'int *' to '__{{global|constant}} int *' changes address space of pointer}} +// expected-error-re@-2{{assigning '__private int *' to '__{{global|constant}} int *' changes address space of pointer}} #endif var_impl = arg_gen; @@ -152,7 +152,7 @@ var_cast4 = (AS int *)arg_priv; #ifndef GENERIC -// expected-error-re@-2{{casting 'int *' to type '__{{global|constant}} int *' changes address space of pointer}} +// expected-error-re@-2{{casting '__private int *' to type '__{{global|constant}} int *' changes address space of pointer}} #endif var_cast5 = (AS int *)arg_gen; @@ -178,7 +178,7 @@ b = var_cmp <= arg_priv; #ifndef GENERIC -// expected-error-re@-2{{comparison between ('__{{global|constant}} int *' and 'int *') which are pointers to non-overlapping address spaces}} +// expected-error-re@-2{{comparison between ('__{{global|constant}} int *' and '__private int *') which are pointers to non-overlapping address spaces}} #endif b = var_cmp >= arg_gen; @@ -204,7 +204,7 @@ b = var_sub - arg_priv; #ifndef GENERIC -// expected-error-re@-2{{arithmetic operation with operands of type ('__{{global|constant}} int *' and 'int *') which are pointers to non-overlapping address spaces}} +// expected-error-re@-2{{arithmetic operation with operands of type ('__{{global|constant}} int *' and '__private int *') which are pointers to non-overlapping address spaces}} #endif b = var_sub - arg_gen; @@ -224,7 +224,7 @@ // expected-error-re@-2{{passing '__{{global|generic}} int *' to parameter of type '__constant int *' changes address space of pointer}} #endif - f_priv(var_sub); // expected-error-re{{passing '__{{global|constant|generic}} int *' to parameter of type 'int *' changes address space of pointer}} + f_priv(var_sub); // expected-error-re{{passing '__{{global|constant|generic}} int *' to parameter of type '__private int *' changes address space of pointer}} f_gen(var_sub); #ifdef CONSTANT @@ -256,7 +256,7 @@ private int *var_priv; var_gen = 0 ? var_cond : var_priv; #ifndef GENERIC -// expected-error-re@-2{{conditional operator with the second and third operands of type ('__{{global|constant}} int *' and 'int *') which are pointers to non-overlapping address spaces}} +// expected-error-re@-2{{conditional operator with the second and third operands of type ('__{{global|constant}} int *' and '__private int *') which are pointers to non-overlapping address spaces}} #endif var_gen = 0 ? var_cond : var_gen; @@ -293,7 +293,7 @@ private char *var_priv_ch; var_void_gen = 0 ? var_cond : var_priv_ch; #ifndef GENERIC -// expected-error-re@-2{{conditional operator with the second and third operands of type ('__{{global|constant}} int *' and 'char *') which are pointers to non-overlapping address spaces}} +// expected-error-re@-2{{conditional operator with the second and third operands of type ('__{{global|constant}} int *' and '__private char *') which are pointers to non-overlapping address spaces}} #else // expected-warning@-4{{pointer type mismatch ('__generic int *' and 'char *')}} #endif Index: test/SemaOpenCL/address-spaces.cl =================================================================== --- test/SemaOpenCL/address-spaces.cl +++ test/SemaOpenCL/address-spaces.cl @@ -17,21 +17,21 @@ g = (global int*) l; // expected-error {{casting '__local int *' to type '__global int *' changes address space of pointer}} g = (global int*) c; // expected-error {{casting '__constant int *' to type '__global int *' changes address space of pointer}} g = (global int*) cc; // expected-error {{casting 'const __constant int *' to type '__global int *' changes address space of pointer}} - g = (global int*) p; // expected-error {{casting 'int *' to type '__global int *' changes address space of pointer}} + g = (global int*) p; // expected-error {{casting '__private int *' to type '__global int *' changes address space of pointer}} l = (local int*) g; // expected-error {{casting '__global int *' to type '__local int *' changes address space of pointer}} l = (local int*) c; // expected-error {{casting '__constant int *' to type '__local int *' changes address space of pointer}} l = (local int*) cc; // expected-error {{casting 'const __constant int *' to type '__local int *' changes address space of pointer}} - l = (local int*) p; // expected-error {{casting 'int *' to type '__local int *' changes address space of pointer}} + l = (local int*) p; // expected-error {{casting '__private int *' to type '__local int *' changes address space of pointer}} c = (constant int*) g; // expected-error {{casting '__global int *' to type '__constant int *' changes address space of pointer}} c = (constant int*) l; // expected-error {{casting '__local int *' to type '__constant int *' changes address space of pointer}} - c = (constant int*) p; // expected-error {{casting 'int *' to type '__constant int *' changes address space of pointer}} + c = (constant int*) p; // expected-error {{casting '__private int *' to type '__constant int *' changes address space of pointer}} - p = (private int*) g; // expected-error {{casting '__global int *' to type 'int *' changes address space of pointer}} - p = (private int*) l; // expected-error {{casting '__local int *' to type 'int *' changes address space of pointer}} - p = (private int*) c; // expected-error {{casting '__constant int *' to type 'int *' changes address space of pointer}} - p = (private int*) cc; // expected-error {{casting 'const __constant int *' to type 'int *' changes address space of pointer}} + p = (private int*) g; // expected-error {{casting '__global int *' to type '__private int *' changes address space of pointer}} + p = (private int*) l; // expected-error {{casting '__local int *' to type '__private int *' changes address space of pointer}} + p = (private int*) c; // expected-error {{casting '__constant int *' to type '__private int *' changes address space of pointer}} + p = (private int*) cc; // expected-error {{casting 'const __constant int *' to type '__private int *' changes address space of pointer}} } void ok_explicit_casts(global int *g, global int* g2, local int* l, local int* l2, private int* p, private int* p2)