summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2011-02-11 19:59:54 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2011-02-11 19:59:54 +0000
commitde32b20bdd1bb32967e52aff6947c0a579363a44 (patch)
tree07f477ff4e1f5f9d45f4b3cdc295d57db7c984e7 /clang/lib
parenta49a02a04f5fc09f67a8bfbe84193e28d7452bfe (diff)
downloadbcm5719-llvm-de32b20bdd1bb32967e52aff6947c0a579363a44.tar.gz
bcm5719-llvm-de32b20bdd1bb32967e52aff6947c0a579363a44.zip
Reject forbidden storage class specifiers in OpenCL. Patch by George Russell!
llvm-svn: 125399
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp14
-rw-r--r--clang/lib/Sema/DeclSpec.cpp20
-rw-r--r--clang/lib/Sema/SemaDecl.cpp4
3 files changed, 28 insertions, 10 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index dfac16a082f..d97b4e30a0a 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -1204,23 +1204,23 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// storage-class-specifier
case tok::kw_typedef:
isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec,
- DiagID);
+ DiagID, getLang());
break;
case tok::kw_extern:
if (DS.isThreadSpecified())
Diag(Tok, diag::ext_thread_before) << "extern";
isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_extern, Loc, PrevSpec,
- DiagID);
+ DiagID, getLang());
break;
case tok::kw___private_extern__:
isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_private_extern, Loc,
- PrevSpec, DiagID);
+ PrevSpec, DiagID, getLang());
break;
case tok::kw_static:
if (DS.isThreadSpecified())
Diag(Tok, diag::ext_thread_before) << "static";
isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, Loc, PrevSpec,
- DiagID);
+ DiagID, getLang());
break;
case tok::kw_auto:
if (getLang().CPlusPlus0x)
@@ -1228,15 +1228,15 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
DiagID);
else
isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec,
- DiagID);
+ DiagID, getLang());
break;
case tok::kw_register:
isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, Loc, PrevSpec,
- DiagID);
+ DiagID, getLang());
break;
case tok::kw_mutable:
isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_mutable, Loc, PrevSpec,
- DiagID);
+ DiagID, getLang());
break;
case tok::kw___thread:
isInvalid = DS.SetStorageClassSpecThread(Loc, PrevSpec, DiagID);
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index 8a35ab70923..bc289ec42c9 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -226,7 +226,25 @@ const char *DeclSpec::getSpecifierName(TQ T) {
bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc,
const char *&PrevSpec,
- unsigned &DiagID) {
+ unsigned &DiagID,
+ const LangOptions &Lang) {
+ // OpenCL prohibits extern, auto, register, and static
+ // It seems sensible to prohibit private_extern too
+ if (Lang.OpenCL) {
+ switch (S) {
+ 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);
+ return true;
+ default:
+ break;
+ }
+ }
+
if (StorageClassSpec != SCS_unspecified) {
// Changing storage class is allowed only if the previous one
// was the 'extern' that is part of a linkage specification and
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d756de5e2db..2807e759b56 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1922,7 +1922,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
// Recover by adding 'static'.
DS.SetStorageClassSpec(DeclSpec::SCS_static, SourceLocation(),
- PrevSpec, DiagID);
+ PrevSpec, DiagID, getLangOptions());
}
// C++ [class.union]p3:
// A storage class is not allowed in a declaration of an
@@ -1935,7 +1935,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
// Recover by removing the storage specifier.
DS.SetStorageClassSpec(DeclSpec::SCS_unspecified, SourceLocation(),
- PrevSpec, DiagID);
+ PrevSpec, DiagID, getLangOptions());
}
// C++ [class.union]p2:
OpenPOWER on IntegriCloud