summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorAnastasia Stulova <anastasia.stulova@arm.com>2015-09-30 14:08:20 +0000
committerAnastasia Stulova <anastasia.stulova@arm.com>2015-09-30 14:08:20 +0000
commitbcea69669f3a2c0aa250274c4ccb823d24ee1f12 (patch)
treed719c7a787dedea057a3cadab88f4a4e31764dab /clang/lib/Sema/SemaDecl.cpp
parent48fefa3724c0d85b49dc78afd9b7c29ab560d190 (diff)
downloadbcm5719-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.cpp87
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)
OpenPOWER on IntegriCloud