Parse qualifiers after comma in declarator lists as a Microsoft extension

MSVC parses and ignores these with a warning.

llvm-svn: 223413
This commit is contained in:
Nico Rieck 2014-12-04 23:31:08 +00:00
parent 3e1ee83626
commit eaaae27bc5
5 changed files with 61 additions and 0 deletions

View File

@ -108,6 +108,9 @@ def ext_alignof_expr : ExtWarn<
def warn_microsoft_dependent_exists : Warning<
"dependent %select{__if_not_exists|__if_exists}0 declarations are ignored">,
InGroup<DiagGroup<"microsoft-exists">>;
def warn_microsoft_qualifiers_ignored : Warning<
"qualifiers after comma in declarator list are ignored">,
InGroup<IgnoredAttributes>;
def ext_c11_generic_selection : Extension<
"generic selections are a C11-specific feature">, InGroup<C11>;

View File

@ -2094,6 +2094,8 @@ private:
SourceLocation AttrNameLoc,
ParsedAttributes &Attrs);
void ParseMicrosoftTypeAttributes(ParsedAttributes &attrs);
void DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
SourceLocation SkipExtendedMicrosoftTypeAttributes();
void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs);
void ParseBorlandTypeAttributes(ParsedAttributes &attrs);
void ParseOpenCLAttributes(ParsedAttributes &attrs);

View File

@ -614,6 +614,42 @@ void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
}
}
void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
SourceLocation StartLoc = Tok.getLocation();
SourceLocation EndLoc = SkipExtendedMicrosoftTypeAttributes();
if (EndLoc.isValid()) {
SourceRange Range(StartLoc, EndLoc);
Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) << Range;
}
}
SourceLocation Parser::SkipExtendedMicrosoftTypeAttributes() {
SourceLocation EndLoc;
while (true) {
switch (Tok.getKind()) {
case tok::kw_const:
case tok::kw_volatile:
case tok::kw___fastcall:
case tok::kw___stdcall:
case tok::kw___thiscall:
case tok::kw___cdecl:
case tok::kw___vectorcall:
case tok::kw___ptr32:
case tok::kw___ptr64:
case tok::kw___w64:
case tok::kw___unaligned:
case tok::kw___sptr:
case tok::kw___uptr:
EndLoc = ConsumeToken();
break;
default:
return EndLoc;
}
}
}
void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
// Treat these like attributes
while (Tok.is(tok::kw___pascal)) {
@ -1732,6 +1768,10 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
// short x, __attribute__((common)) var; -> declarator
MaybeParseGNUAttributes(D);
// MSVC parses but ignores qualifiers after the comma as an extension.
if (getLangOpts().MicrosoftExt)
DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
ParseDeclarator(D);
if (!D.isInvalidType()) {
Decl *ThisDecl = ParseDeclarationAfterDeclarator(D);

View File

@ -85,3 +85,11 @@ int * __uptr __ptr64 pup64;
/* Legal to have nested pointer attributes */
int * __sptr * __ptr32 ppsp32;
// Ignored type qualifiers after comma in declarator lists
typedef int ignored_quals_dummy1, const volatile __ptr32 __ptr64 __w64 __unaligned __sptr __uptr ignored_quals1; // expected-warning {{qualifiers after comma in declarator list are ignored}}
typedef void(*ignored_quals_dummy2)(), __fastcall ignored_quals2; // expected-warning {{qualifiers after comma in declarator list are ignored}}
typedef void(*ignored_quals_dummy3)(), __stdcall ignored_quals3; // expected-warning {{qualifiers after comma in declarator list are ignored}}
typedef void(*ignored_quals_dummy4)(), __thiscall ignored_quals4; // expected-warning {{qualifiers after comma in declarator list are ignored}}
typedef void(*ignored_quals_dummy5)(), __cdecl ignored_quals5; // expected-warning {{qualifiers after comma in declarator list are ignored}}
typedef void(*ignored_quals_dummy6)(), __vectorcall ignored_quals6; // expected-warning {{qualifiers after comma in declarator list are ignored}}

View File

@ -366,3 +366,11 @@ void foo(void) {
template <int *>
struct NullptrArg {};
NullptrArg<nullptr> a;
// Ignored type qualifiers after comma in declarator lists
typedef int ignored_quals_dummy1, const volatile __ptr32 __ptr64 __w64 __unaligned __sptr __uptr ignored_quals1; // expected-warning {{qualifiers after comma in declarator list are ignored}}
typedef void(*ignored_quals_dummy2)(), __fastcall ignored_quals2; // expected-warning {{qualifiers after comma in declarator list are ignored}}
typedef void(*ignored_quals_dummy3)(), __stdcall ignored_quals3; // expected-warning {{qualifiers after comma in declarator list are ignored}}
typedef void(*ignored_quals_dummy4)(), __thiscall ignored_quals4; // expected-warning {{qualifiers after comma in declarator list are ignored}}
typedef void(*ignored_quals_dummy5)(), __cdecl ignored_quals5; // expected-warning {{qualifiers after comma in declarator list are ignored}}
typedef void(*ignored_quals_dummy6)(), __vectorcall ignored_quals6; // expected-warning {{qualifiers after comma in declarator list are ignored}}