diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 14 | ||||
-rw-r--r-- | lib/Sema/DeclSpec.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 4 |
3 files changed, 28 insertions, 10 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index dfac16a082..d97b4e30a0 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/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/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index 8a35ab7092..bc289ec42c 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/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/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index d756de5e2d..2807e759b5 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/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: |