"variable declaration in for loop is a C99-specific feature">, InGroup<C99>;
def ext_c99_compound_literal : Extension<
"compound literals are a C99-specific feature">, InGroup<C99>;
-def ext_c99_flexible_array_member : Extension<
- "flexible array members are a C99-specific feature">, InGroup<C99>;
def ext_enumerator_list_comma_c : Extension<
"commas at the end of enumerator lists are a C99-specific "
"feature">, InGroup<C99>;
"field %0 with variable sized type %1 not at the end of a struct or class is"
" a GNU extension">, InGroup<GNUVariableSizedTypeNotAtEnd>;
-def err_flexible_array_empty_struct : Error<
- "flexible array %0 not allowed in otherwise empty struct">;
+def ext_c99_flexible_array_member : Extension<
+ "flexible array members are a C99 feature">, InGroup<C99>;
+def err_flexible_array_empty_aggregate : Error<
+ "flexible array member %0 not allowed in otherwise empty "
+ "%select{struct|interface|union|class|enum}1 is not allowed">;
def err_flexible_array_has_nonpod_type : Error<
"flexible array member %0 of non-POD element type %1">;
def ext_flexible_array_in_struct : Extension<
"flexible array member %0 in otherwise empty "
"%select{struct|interface|union|class|enum}1 is a Microsoft extension">,
InGroup<Microsoft>;
+def err_flexible_array_union : Error<
+ "flexible array member %0 in a union is not allowed">;
def ext_flexible_array_union_ms : Extension<
"flexible array member %0 in a union is a Microsoft extension">,
InGroup<Microsoft>;
// Microsoft and g++ is more permissive regarding flexible array.
// It will accept flexible array in union and also
// as the sole element of a struct/class.
- if (getLangOpts().MicrosoftExt) {
- if (Record->isUnion())
- Diag(FD->getLocation(), diag::ext_flexible_array_union_ms)
- << FD->getDeclName();
- else if (Fields.size() == 1)
- Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_ms)
- << FD->getDeclName() << Record->getTagKind();
- else
- Diag(FD->getLocation(), diag::ext_c99_flexible_array_member)
- << FD->getDeclName() << Record->getTagKind();
- } else if (getLangOpts().CPlusPlus) {
- if (Record->isUnion())
- Diag(FD->getLocation(), diag::ext_flexible_array_union_gnu)
- << FD->getDeclName();
- else if (Fields.size() == 1)
- Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_gnu)
- << FD->getDeclName() << Record->getTagKind();
- else
- Diag(FD->getLocation(), diag::ext_c99_flexible_array_member)
- << FD->getDeclName() << Record->getTagKind();
- } else if (!getLangOpts().C99) {
- if (Record->isUnion())
- Diag(FD->getLocation(), diag::ext_flexible_array_union_gnu)
- << FD->getDeclName();
- else
- Diag(FD->getLocation(), diag::ext_c99_flexible_array_member)
- << FD->getDeclName() << Record->getTagKind();
- } else if (NumNamedMembers < 1) {
- Diag(FD->getLocation(), diag::err_flexible_array_empty_struct)
- << FD->getDeclName();
- FD->setInvalidDecl();
- EnclosingDecl->setInvalidDecl();
- continue;
- }
+ unsigned DiagID = 0;
+ if (Record->isUnion())
+ DiagID = getLangOpts().MicrosoftExt
+ ? diag::ext_flexible_array_union_ms
+ : getLangOpts().CPlusPlus
+ ? diag::ext_flexible_array_union_gnu
+ : diag::err_flexible_array_union;
+ else if (Fields.size() == 1)
+ DiagID = getLangOpts().MicrosoftExt
+ ? diag::ext_flexible_array_empty_aggregate_ms
+ : getLangOpts().CPlusPlus
+ ? diag::ext_flexible_array_empty_aggregate_gnu
+ : NumNamedMembers < 1
+ ? diag::err_flexible_array_empty_aggregate
+ : 0;
+
+ if (DiagID)
+ Diag(FD->getLocation(), DiagID) << FD->getDeclName()
+ << Record->getTagKind();
+ if (!getLangOpts().C99)
+ Diag(FD->getLocation(), diag::ext_c99_flexible_array_member)
+ << FD->getDeclName() << Record->getTagKind();
+
if (!FD->getType()->isDependentType() &&
!Context.getBaseElementType(FD->getType()).isPODType(Context)) {
Diag(FD->getLocation(), diag::err_flexible_array_has_nonpod_type)