]> granicus.if.org Git - clang/commitdiff
Extend the support for cl-std to include 1.2.
authorTanya Lattner <tonic@nondot.org>
Tue, 19 Jun 2012 23:09:52 +0000 (23:09 +0000)
committerTanya Lattner <tonic@nondot.org>
Tue, 19 Jun 2012 23:09:52 +0000 (23:09 +0000)
Add error checking for the static qualifier which is now allowed in certain situations for OpenCL 1.2. Use the CL version to turn on this feature.
Added test case for 1.2 static storage class feature.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158759 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Frontend/CompilerInvocation.cpp
lib/Sema/DeclSpec.cpp
lib/Sema/SemaDecl.cpp
test/SemaOpenCL/storageclass.cl [new file with mode: 0644]

index d27acf7b9966609dd2a7a20b3fef566cd815c44b..1ed200689493a7d518e51dde695e5065462eeb77 100644 (file)
@@ -5622,6 +5622,10 @@ def err_filter_expression_integral : Error<
 // OpenCL warnings and errors.
 def err_invalid_astype_of_different_size : Error<
   "invalid reinterpretation: sizes of %0 and %1 must match">;
+def err_static_kernel : Error<
+  "kernel functions cannot be declared static">;
+def err_static_function_scope : Error<
+  "variables in function scope cannot be declared static">;
 
 } // end of sema category
 
index 674299223f1a60c1dad738d0dba11d17794ce2f9..6f55a02550d06f04648aab5a75c58c982a11e7d8 100644 (file)
@@ -1848,13 +1848,24 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
     }
   }
 
+  // -cl-std only applies for OpenCL language standards.
+  // Override the -std option in this case.
   if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {
-    if (strcmp(A->getValue(Args), "CL1.1") != 0) {
+    LangStandard::Kind OpenCLLangStd
+    = llvm::StringSwitch<LangStandard::Kind>(A->getValue(Args))
+    .Case("CL", LangStandard::lang_opencl)
+    .Case("CL1.1", LangStandard::lang_opencl11)
+    .Case("CL1.2", LangStandard::lang_opencl12)
+    .Default(LangStandard::lang_unspecified);
+    
+    if (OpenCLLangStd == LangStandard::lang_unspecified) {
       Diags.Report(diag::err_drv_invalid_value)
-        << A->getAsString(Args) << A->getValue(Args);
+      << A->getAsString(Args) << A->getValue(Args);
     }
+    else
+      LangStd = OpenCLLangStd;
   }
-
+  
   CompilerInvocation::setLangDefaults(Opts, IK, LangStd);
 
   // We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension
index f6764c2999454090afb7be3fbba6a5113b124f34..966fee3158e25fc019cdb16adeba875ab28ba97c 100644 (file)
@@ -420,19 +420,27 @@ const char *DeclSpec::getSpecifierName(TQ T) {
 bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
                                    const char *&PrevSpec,
                                    unsigned &DiagID) {
-  // OpenCL 1.1 6.8g: "The extern, static, auto and register storage-class
-  // specifiers are not supported."
+  // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class
+  // specifiers are not supported.
   // It seems sensible to prohibit private_extern too
   // The cl_clang_storage_class_specifiers extension enables support for
   // these storage-class specifiers.
+  // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class
+  // specifiers are not supported."
   if (S.getLangOpts().OpenCL &&
       !S.getOpenCLOptions().cl_clang_storage_class_specifiers) {
     switch (SC) {
     case SCS_extern:
     case SCS_private_extern:
+    case SCS_static:
+        if (S.getLangOpts().OpenCLVersion < 120) {
+          DiagID   = diag::err_not_opencl_storage_class_specifier;
+          PrevSpec = getSpecifierName(SC);
+          return true;
+        }
+        break;
     case SCS_auto:
     case SCS_register:
-    case SCS_static:
       DiagID   = diag::err_not_opencl_storage_class_specifier;
       PrevSpec = getSpecifierName(SC);
       return true;
index 63385ccd196afa118246e6b96398f34154f3305e..81b22141e15c519d8f47d050ff61f5482fa189c2 100644 (file)
@@ -4456,6 +4456,15 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
     return false;
   }
 
+  // OpenCL v1.2 s6.8 -- The static qualifier is valid only in program
+  // scope.
+  if ((getLangOpts().OpenCLVersion >= 120)
+      && NewVD->isStaticLocal()) {
+    Diag(NewVD->getLocation(), diag::err_static_function_scope);
+    NewVD->setInvalidDecl();
+    return false;
+  }
+
   if (NewVD->hasLocalStorage() && T.isObjCGCWeak()
       && !NewVD->hasAttr<BlocksAttr>()) {
     if (getLangOpts().getGC() != LangOptions::NonGC)
@@ -5775,6 +5784,14 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
     }
   }
 
+  // OpenCL v1.2 s6.8 static is invalid for kernel functions.
+  if ((getLangOpts().OpenCLVersion >= 120)
+      && NewFD->hasAttr<OpenCLKernelAttr>()
+      && (SC == SC_Static)) {
+    Diag(D.getIdentifierLoc(), diag::err_static_kernel);
+    D.setInvalidType();
+  }
+
   MarkUnusedFileScopedDecl(NewFD);
 
   if (getLangOpts().CUDA)
diff --git a/test/SemaOpenCL/storageclass.cl b/test/SemaOpenCL/storageclass.cl
new file mode 100644 (file)
index 0000000..c78e7cd
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.2
+
+static int A;
+
+// static is not allowed at local scope.
+void kernel foo() {
+  static int X = 5; // expected-error{{variables in function scope cannot be declared static}} 
+  auto int Y = 7; // expected-error{{OpenCL does not support the 'auto' storage class specifier}}
+}
+
+static void kernel bar() { // expected-error{{kernel functions cannot be declared static}}
+}