"static data member %0 not allowed in %select{anonymous struct|union}1">;
def err_union_member_of_reference_type : Error<
"union member %0 has reference type %1">;
-
+def ext_anonymous_struct_union_qualified : Extension<
+ "anonymous %select{struct|union}0 cannot be '%select{const|volatile|"
+ "restrict}1'">;
def err_different_return_type_for_overriding_virtual_function : Error<
"virtual function %0 has a different return type (%1) than the "
"function it overrides (which has return type %2)">;
SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; }
SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; }
+ /// \brief Clear out all of the type qualifiers.
+ void ClearTypeQualifiers() {
+ TypeQualifiers = 0;
+ TQ_constLoc = SourceLocation();
+ TQ_restrictLoc = SourceLocation();
+ TQ_volatileLoc = SourceLocation();
+ }
+
// function-specifier
bool isInlineSpecified() const { return FS_inline_specified; }
SourceLocation getInlineSpecLoc() const { return FS_inlineLoc; }
PrevSpec, DiagID, getLangOptions());
}
+ // Ignore const/volatile/restrict qualifiers.
+ if (DS.getTypeQualifiers()) {
+ if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
+ Diag(DS.getConstSpecLoc(), diag::ext_anonymous_struct_union_qualified)
+ << Record->isUnion() << 0
+ << FixItHint::CreateRemoval(DS.getConstSpecLoc());
+ if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
+ Diag(DS.getVolatileSpecLoc(), diag::ext_anonymous_struct_union_qualified)
+ << Record->isUnion() << 1
+ << FixItHint::CreateRemoval(DS.getVolatileSpecLoc());
+ if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict)
+ Diag(DS.getRestrictSpecLoc(), diag::ext_anonymous_struct_union_qualified)
+ << Record->isUnion() << 2
+ << FixItHint::CreateRemoval(DS.getRestrictSpecLoc());
+
+ DS.ClearTypeQualifiers();
+ }
+
// C++ [class.union]p2:
// The member-specification of an anonymous union shall only
// define non-static data members. [Note: nested types and
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
struct X {
union {
float f3;
void test_unqual_references();
- struct {
+ struct { // expected-warning{{anonymous structs are a GNU extension}}
int a;
float b;
};
// <rdar://problem/7987650>
namespace test4 {
class A {
- struct {
+ struct { // expected-warning{{anonymous structs are a GNU extension}}
int s0; // expected-note {{declared private here}}
double s1; // expected-note {{declared private here}}
union {
union {
int u0; // expected-note {{declared private here}}
double u1; // expected-note {{declared private here}}
- struct {
+ struct { // expected-warning{{anonymous structs are a GNU extension}}
int us0; // expected-note {{declared private here}}
double us1; // expected-note {{declared private here}}
};
};
}
}
+
+namespace PR8326 {
+ template <class T>
+ class Foo {
+ public:
+ Foo()
+ : x(0)
+ , y(1){
+ }
+
+ private:
+ const union { // expected-warning{{anonymous union cannot be 'const'}}
+ struct { // expected-warning{{anonymous structs are a GNU extension}}
+ T x;
+ T y;
+ };
+ T v[2];
+ };
+ };
+
+ Foo<int> baz;
+}