[cfe-commits] r141271 - in /cfe/trunk: include/clang/Basic/OpenCLExtensions.def include/clang/Sema/DeclSpec.h lib/Parse/ParseDecl.cpp lib/Sema/DeclSpec.cpp lib/Sema/SemaDecl.cpp test/Parser/opencl-storage-class.cl
Peter Collingbourne
peter at pcc.me.uk
Wed Oct 5 20:01:00 PDT 2011
Author: pcc
Date: Wed Oct 5 22:01:00 2011
New Revision: 141271
URL: http://llvm.org/viewvc/llvm-project?rev=141271&view=rev
Log:
OpenCL: add a non-standard extension, cl_clang_storage_class_specifiers,
which enables support for C99 storage-class specifiers.
This extension is intended to be used by implementations to implement
OpenCL C built-in functions.
Modified:
cfe/trunk/include/clang/Basic/OpenCLExtensions.def
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Sema/DeclSpec.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/Parser/opencl-storage-class.cl
Modified: cfe/trunk/include/clang/Basic/OpenCLExtensions.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenCLExtensions.def?rev=141271&r1=141270&r2=141271&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OpenCLExtensions.def (original)
+++ cfe/trunk/include/clang/Basic/OpenCLExtensions.def Wed Oct 5 22:01:00 2011
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+// OpenCL 1.1.
OPENCLEXT(cl_khr_fp64)
OPENCLEXT(cl_khr_int64_base_atomics)
OPENCLEXT(cl_khr_int64_extended_atomics)
@@ -25,4 +26,7 @@
OPENCLEXT(cl_khr_byte_addressable_store)
OPENCLEXT(cl_khr_3d_image_writes)
+// Clang Extensions.
+OPENCLEXT(cl_clang_storage_class_specifiers)
+
#undef OPENCLEXT
Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=141271&r1=141270&r2=141271&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Wed Oct 5 22:01:00 2011
@@ -42,6 +42,7 @@
class NestedNameSpecifierLoc;
class ObjCDeclSpec;
class Preprocessor;
+ class Sema;
class Declarator;
struct TemplateIdAnnotation;
@@ -537,8 +538,8 @@
///
/// TODO: use a more general approach that still allows these
/// diagnostics to be ignored when desired.
- bool SetStorageClassSpec(SCS S, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID, const LangOptions &Lang);
+ bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID);
bool SetStorageClassSpecThread(SourceLocation Loc, const char *&PrevSpec,
unsigned &DiagID);
bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec,
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=141271&r1=141270&r2=141271&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Oct 5 22:01:00 2011
@@ -1945,30 +1945,30 @@
// storage-class-specifier
case tok::kw_typedef:
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec,
- DiagID, getLang());
+ isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
+ PrevSpec, DiagID);
break;
case tok::kw_extern:
if (DS.isThreadSpecified())
Diag(Tok, diag::ext_thread_before) << "extern";
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_extern, Loc, PrevSpec,
- DiagID, getLang());
+ isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
+ PrevSpec, DiagID);
break;
case tok::kw___private_extern__:
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_private_extern, Loc,
- PrevSpec, DiagID, getLang());
+ isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern,
+ Loc, PrevSpec, DiagID);
break;
case tok::kw_static:
if (DS.isThreadSpecified())
Diag(Tok, diag::ext_thread_before) << "static";
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, Loc, PrevSpec,
- DiagID, getLang());
+ isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
+ PrevSpec, DiagID);
break;
case tok::kw_auto:
if (getLang().CPlusPlus0x) {
if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec,
- DiagID, getLang());
+ isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
+ PrevSpec, DiagID);
if (!isInvalid)
Diag(Tok, diag::ext_auto_storage_class)
<< FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
@@ -1976,16 +1976,16 @@
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
DiagID);
} else
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec,
- DiagID, getLang());
+ isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
+ PrevSpec, DiagID);
break;
case tok::kw_register:
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, Loc, PrevSpec,
- DiagID, getLang());
+ isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
+ PrevSpec, DiagID);
break;
case tok::kw_mutable:
- isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_mutable, Loc, PrevSpec,
- DiagID, getLang());
+ isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc,
+ PrevSpec, DiagID);
break;
case tok::kw___thread:
isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec, DiagID);
Modified: cfe/trunk/lib/Sema/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=141271&r1=141270&r2=141271&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Sema/DeclSpec.cpp Wed Oct 5 22:01:00 2011
@@ -15,6 +15,7 @@
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/LocInfoType.h"
#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Sema/Sema.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
@@ -403,21 +404,24 @@
llvm_unreachable("Unknown typespec!");
}
-bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc,
+bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
const char *&PrevSpec,
- unsigned &DiagID,
- const LangOptions &Lang) {
- // OpenCL prohibits extern, auto, register, and static
+ unsigned &DiagID) {
+ // OpenCL 1.1 6.8g: "The extern, static, auto and register storage-class
+ // specifiers are not supported."
// It seems sensible to prohibit private_extern too
- if (Lang.OpenCL) {
- switch (S) {
+ // The cl_clang_storage_class_specifiers extension enables support for
+ // these storage-class specifiers.
+ if (S.getLangOptions().OpenCL &&
+ !S.getOpenCLOptions().cl_clang_storage_class_specifiers) {
+ switch (SC) {
case SCS_extern:
case SCS_private_extern:
case SCS_auto:
case SCS_register:
case SCS_static:
DiagID = diag::err_not_opencl_storage_class_specifier;
- PrevSpec = getSpecifierName(S);
+ PrevSpec = getSpecifierName(SC);
return true;
default:
break;
@@ -427,8 +431,8 @@
if (StorageClassSpec != SCS_unspecified) {
// Maybe this is an attempt to use C++0x 'auto' outside of C++0x mode.
bool isInvalid = true;
- if (TypeSpecType == TST_unspecified && Lang.CPlusPlus) {
- if (S == SCS_auto)
+ if (TypeSpecType == TST_unspecified && S.getLangOptions().CPlusPlus) {
+ if (SC == SCS_auto)
return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID);
if (StorageClassSpec == SCS_auto) {
isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc,
@@ -443,12 +447,12 @@
if (isInvalid &&
!(SCS_extern_in_linkage_spec &&
StorageClassSpec == SCS_extern &&
- S == SCS_typedef))
- return BadSpecifier(S, (SCS)StorageClassSpec, PrevSpec, DiagID);
+ SC == SCS_typedef))
+ return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID);
}
- StorageClassSpec = S;
+ StorageClassSpec = SC;
StorageClassSpecLoc = Loc;
- assert((unsigned)S == StorageClassSpec && "SCS constants overflow bitfield");
+ assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield");
return false;
}
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=141271&r1=141270&r2=141271&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Oct 5 22:01:00 2011
@@ -2592,8 +2592,8 @@
Invalid = true;
// Recover by adding 'static'.
- DS.SetStorageClassSpec(DeclSpec::SCS_static, SourceLocation(),
- PrevSpec, DiagID, getLangOptions());
+ DS.SetStorageClassSpec(*this, DeclSpec::SCS_static, SourceLocation(),
+ PrevSpec, DiagID);
}
// C++ [class.union]p3:
// A storage class is not allowed in a declaration of an
@@ -2605,8 +2605,8 @@
Invalid = true;
// Recover by removing the storage specifier.
- DS.SetStorageClassSpec(DeclSpec::SCS_unspecified, SourceLocation(),
- PrevSpec, DiagID, getLangOptions());
+ DS.SetStorageClassSpec(*this, DeclSpec::SCS_unspecified, SourceLocation(),
+ PrevSpec, DiagID);
}
// Ignore const/volatile/restrict qualifiers.
Modified: cfe/trunk/test/Parser/opencl-storage-class.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/opencl-storage-class.cl?rev=141271&r1=141270&r2=141271&view=diff
==============================================================================
--- cfe/trunk/test/Parser/opencl-storage-class.cl (original)
+++ cfe/trunk/test/Parser/opencl-storage-class.cl Wed Oct 5 22:01:00 2011
@@ -6,4 +6,10 @@
register int b; // expected-error {{OpenCL does not support the 'register' storage class specifier}}
extern int c; // expected-error {{OpenCL does not support the 'extern' storage class specifier}}
auto int d; // expected-error {{OpenCL does not support the 'auto' storage class specifier}}
+
+#pragma OPENCL EXTENSION cl_clang_storage_class_specifiers : enable
+ static int e;
+ register int f;
+ extern int g;
+ auto int h;
}
More information about the cfe-commits
mailing list