forked from OSchip/llvm-project
Add -f[no-]declspec to control recognition of __declspec as a keyword
In versions of clang prior to r238238, __declspec was recognized as a keyword in all modes. It was then changed to only be enabled when Microsoft or Borland extensions were enabled (and for CUDA, as a temporary measure). There is a desire to support __declspec in Playstation code, and possibly other environments. This commit adds a command-line switch to allow explicit enabling/disabling of the recognition of __declspec as a keyword. Recognition is enabled by default in Microsoft, Borland, CUDA, and PS4 environments, and disabled in all other environments. Patch by Warren Ristow! llvm-svn: 249279
This commit is contained in:
parent
f9d71a5439
commit
d170c4b57a
|
@ -90,6 +90,7 @@ LANGOPT(LineComment , 1, 0, "'//' comments")
|
|||
LANGOPT(Bool , 1, 0, "bool, true, and false keywords")
|
||||
LANGOPT(Half , 1, 0, "half keyword")
|
||||
LANGOPT(WChar , 1, CPlusPlus, "wchar_t keyword")
|
||||
LANGOPT(DeclSpecKeyword , 1, 0, "__declspec keyword")
|
||||
BENIGN_LANGOPT(DollarIdents , 1, 1, "'$' in identifiers")
|
||||
BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode")
|
||||
BENIGN_LANGOPT(GNUMode , 1, 1, "GNU extensions")
|
||||
|
|
|
@ -469,8 +469,11 @@ KEYWORD(__array_extent , KEYCXX)
|
|||
KEYWORD(__private_extern__ , KEYALL)
|
||||
KEYWORD(__module_private__ , KEYALL)
|
||||
|
||||
// Extension that will be enabled for Microsoft, Borland and PS4, but can be
|
||||
// disabled via '-fno-declspec'.
|
||||
KEYWORD(__declspec , 0)
|
||||
|
||||
// Microsoft Extension.
|
||||
KEYWORD(__declspec , KEYMS|KEYBORLAND)
|
||||
KEYWORD(__cdecl , KEYALL)
|
||||
KEYWORD(__stdcall , KEYALL)
|
||||
KEYWORD(__fastcall , KEYALL)
|
||||
|
|
|
@ -516,6 +516,8 @@ def fdiagnostics_show_category_EQ : Joined<["-"], "fdiagnostics-show-category=">
|
|||
def fdiagnostics_show_template_tree : Flag<["-"], "fdiagnostics-show-template-tree">,
|
||||
Group<f_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Print a template comparison tree for differing templates">;
|
||||
def fdeclspec : Flag<["-"], "fdeclspec">, Group<f_clang_Group>,
|
||||
HelpText<"Allow __declspec as a keyword">, Flags<[CC1Option]>;
|
||||
def fdollars_in_identifiers : Flag<["-"], "fdollars-in-identifiers">, Group<f_Group>,
|
||||
HelpText<"Allow '$' in identifiers">, Flags<[CC1Option]>;
|
||||
def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group<clang_ignored_f_Group>;
|
||||
|
@ -808,6 +810,8 @@ def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Grou
|
|||
def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group<f_Group>;
|
||||
def fno_diagnostics_show_note_include_stack : Flag<["-"], "fno-diagnostics-show-note-include-stack">,
|
||||
Flags<[CC1Option]>, Group<f_Group>;
|
||||
def fno_declspec : Flag<["-"], "fno-declspec">, Group<f_clang_Group>,
|
||||
HelpText<"Disallow __declspec as a keyword">, Flags<[CC1Option]>;
|
||||
def fno_dollars_in_identifiers : Flag<["-"], "fno-dollars-in-identifiers">, Group<f_Group>,
|
||||
HelpText<"Disallow '$' in identifiers">, Flags<[CC1Option]>;
|
||||
def fno_elide_constructors : Flag<["-"], "fno-elide-constructors">, Group<f_Group>,
|
||||
|
|
|
@ -2165,8 +2165,7 @@ private:
|
|||
void MaybeParseMicrosoftDeclSpecs(ParsedAttributes &Attrs,
|
||||
SourceLocation *End = nullptr) {
|
||||
const auto &LO = getLangOpts();
|
||||
if ((LO.MicrosoftExt || LO.Borland || LO.CUDA) &&
|
||||
Tok.is(tok::kw___declspec))
|
||||
if (LO.DeclSpecKeyword && Tok.is(tok::kw___declspec))
|
||||
ParseMicrosoftDeclSpecs(Attrs, End);
|
||||
}
|
||||
void ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs,
|
||||
|
|
|
@ -220,10 +220,7 @@ void IdentifierTable::AddKeywords(const LangOptions &LangOpts) {
|
|||
AddKeyword("__unknown_anytype", tok::kw___unknown_anytype, KEYALL,
|
||||
LangOpts, *this);
|
||||
|
||||
// FIXME: __declspec isn't really a CUDA extension, however it is required for
|
||||
// supporting cuda_builtin_vars.h, which uses __declspec(property). Once that
|
||||
// has been rewritten in terms of something more generic, remove this code.
|
||||
if (LangOpts.CUDA)
|
||||
if (LangOpts.DeclSpecKeyword)
|
||||
AddKeyword("__declspec", tok::kw___declspec, KEYALL, LangOpts, *this);
|
||||
}
|
||||
|
||||
|
|
|
@ -4610,6 +4610,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
options::OPT_fno_borland_extensions, false))
|
||||
CmdArgs.push_back("-fborland-extensions");
|
||||
|
||||
// -fno-declspec is default, except for PS4.
|
||||
if (Args.hasFlag(options::OPT_fdeclspec, options::OPT_fno_declspec,
|
||||
getToolChain().getTriple().isPS4()))
|
||||
CmdArgs.push_back("-fdeclspec");
|
||||
else if (Args.hasArg(options::OPT_fno_declspec))
|
||||
CmdArgs.push_back("-fno-declspec"); // Explicitly disabling __declspec.
|
||||
|
||||
// -fthreadsafe-static is default, except for MSVC compatibility versions less
|
||||
// than 19.
|
||||
if (!Args.hasFlag(options::OPT_fthreadsafe_statics,
|
||||
|
|
|
@ -1826,6 +1826,7 @@ LangOptions getFormattingLangOpts(const FormatStyle &Style) {
|
|||
LangOpts.ObjC1 = 1;
|
||||
LangOpts.ObjC2 = 1;
|
||||
LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally.
|
||||
LangOpts.DeclSpecKeyword = 1; // To get __declspec.
|
||||
return LangOpts;
|
||||
}
|
||||
|
||||
|
|
|
@ -1630,6 +1630,17 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
|
|||
Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns);
|
||||
Opts.GNUAsm = !Args.hasArg(OPT_fno_gnu_inline_asm);
|
||||
|
||||
// __declspec is enabled by default for the PS4 by the driver, and also
|
||||
// enabled for Microsoft Extensions or Borland Extensions, here.
|
||||
//
|
||||
// FIXME: __declspec is also currently enabled for CUDA, but isn't really a
|
||||
// CUDA extension, however it is required for supporting cuda_builtin_vars.h,
|
||||
// which uses __declspec(property). Once that has been rewritten in terms of
|
||||
// something more generic, remove the Opts.CUDA term here.
|
||||
Opts.DeclSpecKeyword =
|
||||
Args.hasFlag(OPT_fdeclspec, OPT_fno_declspec,
|
||||
(Opts.MicrosoftExt || Opts.Borland || Opts.CUDA));
|
||||
|
||||
if (!Opts.CurrentModule.empty() && !Opts.ImplementationOfModule.empty() &&
|
||||
Opts.CurrentModule != Opts.ImplementationOfModule) {
|
||||
Diags.Report(diag::err_conflicting_module_names)
|
||||
|
|
|
@ -532,9 +532,7 @@ bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
|
|||
/// extended-decl-modifier extended-decl-modifier-seq
|
||||
void Parser::ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs,
|
||||
SourceLocation *End) {
|
||||
assert((getLangOpts().MicrosoftExt || getLangOpts().Borland ||
|
||||
getLangOpts().CUDA) &&
|
||||
"Incorrect language options for parsing __declspec");
|
||||
assert(getLangOpts().DeclSpecKeyword && "__declspec keyword is not enabled");
|
||||
assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
|
||||
|
||||
while (Tok.is(tok::kw___declspec)) {
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
|
||||
// RUN: %clang_cc1 -std=c99 -fms-extensions -E %s -o - \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-MS-KEYWORDS %s
|
||||
// RUN: %clang_cc1 -std=c99 -fdeclspec -E %s -o - \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-DECLSPEC-KEYWORD %s
|
||||
// RUN: %clang_cc1 -std=c99 -fms-extensions -fno-declspec -E %s -o - \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-MS-KEYWORDS-WITHOUT-DECLSPEC %s
|
||||
|
||||
void f() {
|
||||
// CHECK-NONE: int asm
|
||||
|
@ -22,8 +26,19 @@ void f() {
|
|||
|
||||
// CHECK-NONE: no_ms_wchar
|
||||
// CHECK-MS-KEYWORDS: has_ms_wchar
|
||||
// CHECK-MS-KEYWORDS-WITHOUT-DECLSPEC: has_ms_wchar
|
||||
#if __is_identifier(__wchar_t)
|
||||
void no_ms_wchar();
|
||||
#else
|
||||
void has_ms_wchar();
|
||||
#endif
|
||||
|
||||
// CHECK-NONE: no_declspec
|
||||
// CHECK-MS-KEYWORDS: has_declspec
|
||||
// CHECK-MS-KEYWORDS-WITHOUT-DECLSPEC: no_declspec
|
||||
// CHECK-DECLSPEC-KEYWORD: has_declspec
|
||||
#if __is_identifier(__declspec)
|
||||
void no_declspec();
|
||||
#else
|
||||
void has_declspec();
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
// 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 -fdeclspec -DDECLSPEC -fsyntax-only %s
|
||||
// RUN: %clang_cc1 -std=c++03 -fms-extensions -DDECLSPEC -fsyntax-only %s
|
||||
// RUN: %clang_cc1 -std=c++03 -fborland-extensions -DDECLSPEC -fsyntax-only %s
|
||||
// RUN: %clang_cc1 -std=c++03 -fms-extensions -fno-declspec -fsyntax-only %s
|
||||
// RUN: %clang_cc1 -std=c++03 -fborland-extensions -fno-declspec -fsyntax-only %s
|
||||
// RUN: %clang_cc1 -std=c++03 -fno-declspec -fdeclspec -DDECLSPEC -fsyntax-only %s
|
||||
// RUN: %clang_cc1 -std=c++03 -fdeclspec -fno-declspec -fsyntax-only %s
|
||||
// RUN: %clang_cc1 -std=c++03 -fms-extensions -fno-declspec -fdeclspec -DDECLSPEC -fsyntax-only %s
|
||||
// RUN: %clang_cc1 -std=c++03 -fms-extensions -fdeclspec -fno-declspec -fsyntax-only %s
|
||||
// RUN: %clang -std=c++03 -target i686-windows-msvc -DDECLSPEC -fsyntax-only %s
|
||||
// RUN: %clang -std=c++03 -target x86_64-scei-ps4 -DDECLSPEC -fsyntax-only %s
|
||||
// RUN: %clang -std=c++03 -target i686-windows-msvc -fno-declspec -fsyntax-only %s
|
||||
// RUN: %clang -std=c++03 -target x86_64-scei-ps4 -fno-declspec -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 +25,12 @@
|
|||
#define CONCEPTS_KEYWORD(NAME) NOT_KEYWORD(NAME)
|
||||
#endif
|
||||
|
||||
#ifdef DECLSPEC
|
||||
#define DECLSPEC_KEYWORD(NAME) IS_KEYWORD(NAME)
|
||||
#else
|
||||
#define DECLSPEC_KEYWORD(NAME) NOT_KEYWORD(NAME)
|
||||
#endif
|
||||
|
||||
#ifdef CXX11
|
||||
#define CXX11_KEYWORD(NAME) IS_KEYWORD(NAME)
|
||||
#define CXX11_TYPE(NAME) IS_TYPE(NAME)
|
||||
|
@ -38,6 +57,9 @@ CXX11_KEYWORD(thread_local);
|
|||
CONCEPTS_KEYWORD(concept);
|
||||
CONCEPTS_KEYWORD(requires);
|
||||
|
||||
// __declspec extension
|
||||
DECLSPEC_KEYWORD(__declspec);
|
||||
|
||||
// Clang extension
|
||||
IS_KEYWORD(__char16_t);
|
||||
IS_TYPE(__char16_t);
|
||||
|
|
Loading…
Reference in New Issue