diff options
author | Anastasia Stulova <anastasia.stulova@arm.com> | 2015-09-30 14:08:20 +0000 |
---|---|---|
committer | Anastasia Stulova <anastasia.stulova@arm.com> | 2015-09-30 14:08:20 +0000 |
commit | bcea69669f3a2c0aa250274c4ccb823d24ee1f12 (patch) | |
tree | d719c7a787dedea057a3cadab88f4a4e31764dab /clang/lib/Sema/SemaDecl.cpp | |
parent | 48fefa3724c0d85b49dc78afd9b7c29ab560d190 (diff) | |
download | bcm5719-llvm-bcea69669f3a2c0aa250274c4ccb823d24ee1f12.tar.gz bcm5719-llvm-bcea69669f3a2c0aa250274c4ccb823d24ee1f12.zip |
[OpenCL 2.0] Enable program scope variables, Section 6.5.1.
- Remove virtual SC_OpenCLWorkGroupLocal storage type specifier
as it conflicts with static local variables now and prevents
diagnosing static local address space variables correctly.
- Allow static local and global variables (OpenCL2.0 s6.8 and s6.5.1).
- Improve diagnostics of allowed ASes for variables in different scopes:
(i) Global or static local variables have to be in global
or constant ASes (OpenCL1.2 s6.5, OpenCL2.0 s6.5.1);
(ii) Non-kernel function variables can't be declared in local
or constant ASes (OpenCL1.1 s6.5.2 and s6.5.3).
http://reviews.llvm.org/D13105
llvm-svn: 248906
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 87 |
1 files changed, 62 insertions, 25 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 592f393d464..571c9baa048 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -5687,12 +5687,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } if (getLangOpts().OpenCL) { - // Set up the special work-group-local storage class for variables in the - // OpenCL __local address space. - if (R.getAddressSpace() == LangAS::opencl_local) { - SC = SC_OpenCLWorkGroupLocal; - } - // OpenCL v1.2 s6.9.b p4: // The sampler type cannot be used with the __local and __global address // space qualifiers. @@ -5759,8 +5753,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, break; case SC_PrivateExtern: llvm_unreachable("C storage class in c++!"); - case SC_OpenCLWorkGroupLocal: - llvm_unreachable("OpenCL storage class in c++!"); } } @@ -6034,7 +6026,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, case SC_Static: case SC_Extern: case SC_PrivateExtern: - case SC_OpenCLWorkGroupLocal: break; } } else if (SC == SC_Register) { @@ -6428,31 +6419,79 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { // This includes arrays of objects with address space qualifiers, but not // automatic variables that point to other address spaces. // ISO/IEC TR 18037 S5.1.2 - if (NewVD->hasLocalStorage() && T.getAddressSpace() != 0) { + if (!getLangOpts().OpenCL + && NewVD->hasLocalStorage() && T.getAddressSpace() != 0) { Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl); NewVD->setInvalidDecl(); return; } - // OpenCL v1.2 s6.5 - All program scope variables must be declared in the - // __constant address space. - if (getLangOpts().OpenCL && NewVD->isFileVarDecl() - && T.getAddressSpace() != LangAS::opencl_constant - && !T->isSamplerT()){ - Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space); - NewVD->setInvalidDecl(); - return; - } - // OpenCL v1.2 s6.8 -- The static qualifier is valid only in program // scope. - if ((getLangOpts().OpenCLVersion >= 120) - && NewVD->isStaticLocal()) { + if (getLangOpts().OpenCLVersion == 120 && + !getOpenCLOptions().cl_clang_storage_class_specifiers && + NewVD->isStaticLocal()) { Diag(NewVD->getLocation(), diag::err_static_function_scope); NewVD->setInvalidDecl(); return; } + // OpenCL v1.2 s6.5 - All program scope variables must be declared in the + // __constant address space. + // OpenCL v2.0 s6.5.1 - Variables defined at program scope and static + // variables inside a function can also be declared in the global + // address space. + if (getLangOpts().OpenCL) { + if (NewVD->isFileVarDecl()) { + if (!T->isSamplerT() && + !(T.getAddressSpace() == LangAS::opencl_constant || + (T.getAddressSpace() == LangAS::opencl_global && + getLangOpts().OpenCLVersion == 200))) { + if (getLangOpts().OpenCLVersion == 200) + Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) + << "global or constant"; + else + Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) + << "constant"; + NewVD->setInvalidDecl(); + return; + } + } else { + // OpenCL v2.0 s6.5.1 - Variables defined at program scope and static + // variables inside a function can also be declared in the global + // address space. + if (NewVD->isStaticLocal() && + !(T.getAddressSpace() == LangAS::opencl_constant || + (T.getAddressSpace() == LangAS::opencl_global && + getLangOpts().OpenCLVersion == 200))) { + if (getLangOpts().OpenCLVersion == 200) + Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) + << "global or constant"; + else + Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) + << "constant"; + NewVD->setInvalidDecl(); + return; + } + // OpenCL v1.1 s6.5.2 and s6.5.3 no local or constant variables + // in functions. + if (T.getAddressSpace() == LangAS::opencl_constant || + T.getAddressSpace() == LangAS::opencl_local) { + FunctionDecl *FD = getCurFunctionDecl(); + if (FD && !FD->hasAttr<OpenCLKernelAttr>()) { + if (T.getAddressSpace() == LangAS::opencl_constant) + Diag(NewVD->getLocation(), diag::err_opencl_non_kernel_variable) + << "constant"; + else + Diag(NewVD->getLocation(), diag::err_opencl_non_kernel_variable) + << "local"; + NewVD->setInvalidDecl(); + return; + } + } + } + } + if (NewVD->hasLocalStorage() && T.isObjCGCWeak() && !NewVD->hasAttr<BlocksAttr>()) { if (getLangOpts().getGC() != LangOptions::NonGC) @@ -9158,7 +9197,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // OpenCL 1.1 6.5.2: "Variables allocated in the __local address space inside // a kernel function cannot be initialized." - if (VDecl->getStorageClass() == SC_OpenCLWorkGroupLocal) { + if (VDecl->getType().getAddressSpace() == LangAS::opencl_local) { Diag(VDecl->getLocation(), diag::err_local_cant_init); VDecl->setInvalidDecl(); return; @@ -9729,8 +9768,6 @@ void Sema::ActOnCXXForRangeDecl(Decl *D) { case SC_Register: Error = 4; break; - case SC_OpenCLWorkGroupLocal: - llvm_unreachable("Unexpected storage class"); } if (Error != -1) { Diag(VD->getOuterLocStart(), diag::err_for_range_storage_class) |