forked from OSchip/llvm-project
Allow type definitions inside anonymous struct/union in Microsoft mode.
llvm-svn: 113354
This commit is contained in:
parent
2907d2e419
commit
4ad4b58639
|
@ -227,3 +227,6 @@ def NonGCC : DiagGroup<"non-gcc",
|
|||
|
||||
// A warning group for warnings about GCC extensions.
|
||||
def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>;
|
||||
|
||||
// A warning group for warnings about Microsoft extensions.
|
||||
def Microsoft : DiagGroup<"microsoft">;
|
||||
|
|
|
@ -2850,6 +2850,9 @@ def err_anonymous_struct_member_redecl : Error<
|
|||
"member of anonymous struct redeclares %0">;
|
||||
def err_anonymous_record_with_type : Error<
|
||||
"types cannot be declared in an anonymous %select{struct|union}0">;
|
||||
def ext_anonymous_record_with_type : Extension<
|
||||
"types declared in an anonymous %select{struct|union}0 are a Microsoft extension">,
|
||||
InGroup<Microsoft>;
|
||||
def err_anonymous_record_with_function : Error<
|
||||
"functions cannot be declared in an anonymous %select{struct|union}0">;
|
||||
def err_anonymous_record_with_static : Error<
|
||||
|
|
|
@ -1898,10 +1898,16 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
|
|||
} else if (RecordDecl *MemRecord = dyn_cast<RecordDecl>(*Mem)) {
|
||||
if (!MemRecord->isAnonymousStructOrUnion() &&
|
||||
MemRecord->getDeclName()) {
|
||||
// This is a nested type declaration.
|
||||
Diag(MemRecord->getLocation(), diag::err_anonymous_record_with_type)
|
||||
<< (int)Record->isUnion();
|
||||
Invalid = true;
|
||||
// Visual C++ allows type definition in anonymous struct or union.
|
||||
if (getLangOptions().Microsoft)
|
||||
Diag(MemRecord->getLocation(), diag::ext_anonymous_record_with_type)
|
||||
<< (int)Record->isUnion();
|
||||
else {
|
||||
// This is a nested type declaration.
|
||||
Diag(MemRecord->getLocation(), diag::err_anonymous_record_with_type)
|
||||
<< (int)Record->isUnion();
|
||||
Invalid = true;
|
||||
}
|
||||
}
|
||||
} else if (isa<AccessSpecDecl>(*Mem)) {
|
||||
// Any access specifier is fine.
|
||||
|
@ -1915,9 +1921,17 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
|
|||
DK = diag::err_anonymous_record_with_function;
|
||||
else if (isa<VarDecl>(*Mem))
|
||||
DK = diag::err_anonymous_record_with_static;
|
||||
Diag((*Mem)->getLocation(), DK)
|
||||
|
||||
// Visual C++ allows type definition in anonymous struct or union.
|
||||
if (getLangOptions().Microsoft &&
|
||||
DK == diag::err_anonymous_record_with_type)
|
||||
Diag((*Mem)->getLocation(), diag::ext_anonymous_record_with_type)
|
||||
<< (int)Record->isUnion();
|
||||
else {
|
||||
Diag((*Mem)->getLocation(), DK)
|
||||
<< (int)Record->isUnion();
|
||||
Invalid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-extensions -fexceptions
|
||||
// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions -fexceptions
|
||||
|
||||
|
||||
// ::type_info is predeclared with forward class declartion
|
||||
|
@ -30,6 +30,48 @@ struct Derived : Base {
|
|||
virtual void f3();
|
||||
};
|
||||
|
||||
|
||||
// MSVC allows type definition in anonymous union and struct
|
||||
struct A
|
||||
{
|
||||
union
|
||||
{
|
||||
int a;
|
||||
struct B // expected-warning {{types declared in an anonymous union are a Microsoft extension}}
|
||||
{
|
||||
int c;
|
||||
} d;
|
||||
|
||||
union C // expected-warning {{types declared in an anonymous union are a Microsoft extension}}
|
||||
{
|
||||
int e;
|
||||
int ee;
|
||||
} f;
|
||||
|
||||
typedef int D; // expected-warning {{types declared in an anonymous union are a Microsoft extension}}
|
||||
struct F; // expected-warning {{types declared in an anonymous union are a Microsoft extension}}
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
int a2;
|
||||
|
||||
struct B2 // expected-warning {{types declared in an anonymous struct are a Microsoft extension}}
|
||||
{
|
||||
int c2;
|
||||
} d2;
|
||||
|
||||
union C2 // expected-warning {{types declared in an anonymous struct are a Microsoft extension}}
|
||||
{
|
||||
int e2;
|
||||
int ee2;
|
||||
} f2;
|
||||
|
||||
typedef int D2; // expected-warning {{types declared in an anonymous struct are a Microsoft extension}}
|
||||
struct F2; // expected-warning {{types declared in an anonymous struct are a Microsoft extension}}
|
||||
};
|
||||
};
|
||||
|
||||
// __stdcall handling
|
||||
struct M {
|
||||
int __stdcall addP();
|
||||
|
|
Loading…
Reference in New Issue