Index: include/clang/Basic/LangOptions.def =================================================================== --- include/clang/Basic/LangOptions.def +++ include/clang/Basic/LangOptions.def @@ -78,6 +78,7 @@ LANGOPT(CPlusPlus1z , 1, 0, "C++1z") LANGOPT(ObjC1 , 1, 0, "Objective-C 1") LANGOPT(ObjC2 , 1, 0, "Objective-C 2") +LANGOPT(SceExt , 1, 0, "Sony PlayStation(R) extensions") BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0, "Objective-C auto-synthesized properties") BENIGN_LANGOPT(EncodeExtendedBlockSig , 1, 0, Index: include/clang/Basic/TokenKinds.def =================================================================== --- include/clang/Basic/TokenKinds.def +++ include/clang/Basic/TokenKinds.def @@ -240,6 +240,7 @@ // KEYNOOPENCL - This is a keyword that is not supported in OpenCL // KEYALTIVEC - This is a keyword in AltiVec // KEYBORLAND - This is a keyword if Borland extensions are enabled +// KEYSCE - This is a keyword if Sony PlayStation extensions are enabled // BOOLSUPPORT - This is a keyword if 'bool' is a built-in type // HALFSUPPORT - This is a keyword if 'half' is a built-in type // WCHARSUPPORT - This is a keyword if 'wchar_t' is a built-in type @@ -468,7 +469,7 @@ KEYWORD(__module_private__ , KEYALL) // Microsoft Extension. -KEYWORD(__declspec , KEYMS|KEYBORLAND) +KEYWORD(__declspec , KEYMS|KEYBORLAND|KEYSCE) KEYWORD(__cdecl , KEYALL) KEYWORD(__stdcall , KEYALL) KEYWORD(__fastcall , KEYALL) Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -561,6 +561,8 @@ HelpText<"Use the native half type for __fp16 instead of promoting to float">; def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">, HelpText<"Allow function arguments and returns of type half">; +def fsce_extensions : Flag<["-"], "fsce-extensions">, + HelpText<"">; //===----------------------------------------------------------------------===// // Header Search Options Index: include/clang/Parse/Parser.h =================================================================== --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -2161,7 +2161,7 @@ void MaybeParseMicrosoftDeclSpecs(ParsedAttributes &Attrs, SourceLocation *End = nullptr) { const auto &LO = getLangOpts(); - if ((LO.MicrosoftExt || LO.Borland || LO.CUDA) && + if ((LO.MicrosoftExt || LO.Borland || LO.CUDA || LO.SceExt) && Tok.is(tok::kw___declspec)) ParseMicrosoftDeclSpecs(Attrs, End); } Index: lib/Basic/IdentifierTable.cpp =================================================================== --- lib/Basic/IdentifierTable.cpp +++ lib/Basic/IdentifierTable.cpp @@ -110,7 +110,8 @@ HALFSUPPORT = 0x08000, KEYCONCEPTS = 0x10000, KEYOBJC2 = 0x20000, - KEYALL = (0x3ffff & ~KEYNOMS18 & + KEYSCE = 0x40000, + KEYALL = (0x7ffff & ~KEYNOMS18 & ~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude. }; @@ -134,6 +135,7 @@ if (LangOpts.GNUKeywords && (Flags & KEYGNU)) return KS_Extension; if (LangOpts.MicrosoftExt && (Flags & KEYMS)) return KS_Extension; if (LangOpts.Borland && (Flags & KEYBORLAND)) return KS_Extension; + if (LangOpts.SceExt && (Flags & KEYSCE)) return KS_Extension; if (LangOpts.Bool && (Flags & BOOLSUPPORT)) return KS_Enabled; if (LangOpts.Half && (Flags & HALFSUPPORT)) return KS_Enabled; if (LangOpts.WChar && (Flags & WCHARSUPPORT)) return KS_Enabled; Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -4340,6 +4340,9 @@ IsWindowsMSVC)) CmdArgs.push_back("-fms-extensions"); + if (getToolChain().getTriple().isPS4()) + CmdArgs.push_back("-fsce-extensions"); + // -fno-use-line-directives is default. if (Args.hasFlag(options::OPT_fuse_line_directives, options::OPT_fno_use_line_directives, false)) Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1372,6 +1372,9 @@ CompilerInvocation::setLangDefaults(Opts, IK, LangStd); + if (Args.hasArg(OPT_fsce_extensions)) + Opts.SceExt = 1; + // We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension // keywords. This behavior is provided by GCC's poorly named '-fasm' flag, // while a subset (the non-C++ GNU keywords) is provided by GCC's Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -533,7 +533,7 @@ void Parser::ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs, SourceLocation *End) { assert((getLangOpts().MicrosoftExt || getLangOpts().Borland || - getLangOpts().CUDA) && + getLangOpts().CUDA || getLangOpts().SceExt) && "Incorrect language options for parsing __declspec"); assert(Tok.is(tok::kw___declspec) && "Not a declspec!"); Index: test/Lexer/keywords_test.c =================================================================== --- test/Lexer/keywords_test.c +++ test/Lexer/keywords_test.c @@ -9,6 +9,8 @@ // RUN: %clang_cc1 -std=c99 -fms-extensions -E %s -o - \ // RUN: | FileCheck --check-prefix=CHECK-MS-KEYWORDS %s +// RUN: %clang_cc1 -std=c99 -fsce-extensions -E %s -o - \ +// RUN: | FileCheck --check-prefix=CHECK-SCE-KEYWORDS %s void f() { // CHECK-NONE: int asm @@ -27,3 +29,12 @@ #else void has_ms_wchar(); #endif + +// CHECK-NONE: no_declspec +// CHECK-MS-KEYWORDS: has_declspec +// CHECK-SCE-KEYWORDS: has_declspec +#if __is_identifier(__declspec) +void no_declspec(); +#else +void has_declspec(); +#endif Index: test/Lexer/keywords_test.cpp =================================================================== --- test/Lexer/keywords_test.cpp +++ test/Lexer/keywords_test.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -std=c++03 -fsyntax-only %s // RUN: %clang_cc1 -std=c++11 -DCXX11 -fsyntax-only %s // RUN: %clang_cc1 -std=c++14 -fconcepts-ts -DCXX11 -DCONCEPTS -fsyntax-only %s +// RUN: %clang_cc1 -std=c++03 -fsce-extensions -DSCE -fsyntax-only %s #define IS_KEYWORD(NAME) _Static_assert(!__is_identifier(NAME), #NAME) #define NOT_KEYWORD(NAME) _Static_assert(__is_identifier(NAME), #NAME) @@ -12,6 +13,12 @@ #define CONCEPTS_KEYWORD(NAME) NOT_KEYWORD(NAME) #endif +#ifdef SCE +#define SCE_KEYWORD(NAME) IS_KEYWORD(NAME) +#else +#define SCE_KEYWORD(NAME) NOT_KEYWORD(NAME) +#endif + #ifdef CXX11 #define CXX11_KEYWORD(NAME) IS_KEYWORD(NAME) #define CXX11_TYPE(NAME) IS_TYPE(NAME) @@ -38,6 +45,9 @@ CONCEPTS_KEYWORD(concept); CONCEPTS_KEYWORD(requires); +// SCE extensions +SCE_KEYWORD(__declspec); + // Clang extension IS_KEYWORD(__char16_t); IS_TYPE(__char16_t);