def UnknownPragmas : DiagGroup<"unknown-pragmas">;
def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
def UnknownAttributes : DiagGroup<"attributes">;
+def IgnoredAttributes : DiagGroup<"ignored-attributes">;
def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args",
[CXX98CompatUnnamedTypeTemplateArgs]>;
def UnusedArgument : DiagGroup<"unused-argument">;
def warn_attribute_ignored : Warning<"%0 attribute ignored">;
def warn_unknown_attribute_ignored : Warning<
"unknown attribute %0 ignored">, InGroup<UnknownAttributes>;
+def warn_declspec_attribute_ignored : Warning<
+ "attribute %0 is ignored, place it after \"%select{class|struct|union|enum}1\" to apply attribute to type declaration">, InGroup<IgnoredAttributes>;
def warn_attribute_precede_definition : Warning<
"attribute declaration must precede definition">;
def warn_attribute_void_function_method : Warning<
bool emittedWarning = false;
if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
- ProcessDeclAttributeList(S, Record, DS.getAttributes().getList());
-
if (!Record->getDeclName() && Record->isCompleteDefinition() &&
DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
if (getLangOptions().CPlusPlus ||
<< Tag->getTagKind()
<< FixItHint::CreateRemoval(DS.getModulePrivateSpecLoc());
- // FIXME: Warn on useless attributes
+ // Warn about ignored type attributes, for example:
+ // __attribute__((aligned)) struct A;
+ // Attributes should be placed after tag to apply to type declaration.
+ if (!DS.getAttributes().empty()) {
+ DeclSpec::TST TypeSpecType = DS.getTypeSpecType();
+ if (TypeSpecType == DeclSpec::TST_class ||
+ TypeSpecType == DeclSpec::TST_struct ||
+ TypeSpecType == DeclSpec::TST_union ||
+ TypeSpecType == DeclSpec::TST_enum) {
+ AttributeList* attrs = DS.getAttributes().getList();
+ while (attrs) {
+ Diag(attrs->getScopeLoc(),
+ diag::warn_declspec_attribute_ignored)
+ << attrs->getName()
+ << (TypeSpecType == DeclSpec::TST_class ? 0 :
+ TypeSpecType == DeclSpec::TST_struct ? 1 :
+ TypeSpecType == DeclSpec::TST_union ? 2 : 3);
+ attrs = attrs->getNext();
+ }
+ }
+ }
return TagD;
}
// Test for unexpanded parameter packs in declarations.
template<typename T, typename... Types>
// FIXME: this should test that the diagnostic reads "type contains..."
-alignas(Types) // expected-error{{expression contains unexpanded parameter pack 'Types'}}
-struct TestUnexpandedDecls : T{
+struct alignas(Types) TestUnexpandedDecls : T{ // expected-error{{expression contains unexpanded parameter pack 'Types'}}
void member_function(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
void member_function () throw(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
operator Types() const; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
namespace Test10 {
struct A;
- DEFAULT class B {
+ class DEFAULT B {
void foo(A*);
};
--- /dev/null
+// RUN: %clang_cc1 %s -verify -fsyntax-only\r
+\r
+__attribute__((visibility("hidden"))) __attribute__((aligned)) struct A; // expected-warning{{attribute 'visibility' is ignored, place it after "struct" to apply attribute to type declaration}} \\r
+// expected-warning{{attribute 'aligned' is ignored, place it after "struct" to apply attribute to type declaration}}\r
+__attribute__((visibility("hidden"))) __attribute__((aligned)) union B; // expected-warning{{attribute 'visibility' is ignored, place it after "union" to apply attribute to type declaration}} \\r
+// expected-warning{{attribute 'aligned' is ignored, place it after "union" to apply attribute to type declaration}} \r
+__attribute__((visibility("hidden"))) __attribute__((aligned)) enum C {C}; // expected-warning{{attribute 'visibility' is ignored, place it after "enum" to apply attribute to type declaration}} \\r
+// expected-warning{{attribute 'aligned' is ignored, place it after "enum" to apply attribute to type declaration}}\r
+\r
+__attribute__((visibility("hidden"))) __attribute__((aligned)) struct D {} d;\r
+__attribute__((visibility("hidden"))) __attribute__((aligned)) union E {} e;\r
+__attribute__((visibility("hidden"))) __attribute__((aligned)) enum F {F} f;\r
typedef struct foo foo_dep __attribute__((deprecated));
foo_dep *test2; // expected-warning {{'foo_dep' is deprecated}}
-struct bar_dep __attribute__((deprecated,
- invalid_attribute)); // expected-warning {{unknown attribute 'invalid_attribute' ignored}}
+struct __attribute__((deprecated,
+ invalid_attribute)) bar_dep ; // expected-warning {{unknown attribute 'invalid_attribute' ignored}}
struct bar_dep *test3; // expected-warning {{'bar_dep' is deprecated}}
}
// Aligned struct.
-__attribute__((aligned(16))) struct A {
+struct __attribute__((aligned(16))) A {
char buffer[16];
};
void test2(char *P) {
int member alignas(8);
};
-template <unsigned A> alignas(A) struct align_class_template {};
+template <unsigned A> struct alignas(A) align_class_template {};
// FIXME: these should not error
template <typename... T> alignas(T...) struct align_class_temp_pack_type {}; // expected-error{{pack expansions in alignment specifiers are not supported yet}}
--- /dev/null
+// RUN: %clang_cc1 %s -verify -fsyntax-only\r
+\r
+namespace test1 {\r
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) class A; // expected-warning{{attribute 'visibility' is ignored, place it after "class" to apply attribute to type declaration}} \\r
+ // expected-warning{{attribute 'aligned' is ignored, place it after "class" to apply attribute to type declaration}}\r
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) struct B; // expected-warning{{attribute 'visibility' is ignored, place it after "struct" to apply attribute to type declaration}} \\r
+ // expected-warning{{attribute 'aligned' is ignored, place it after "struct" to apply attribute to type declaration}}\r
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) union C; // expected-warning{{attribute 'visibility' is ignored, place it after "union" to apply attribute to type declaration}} \\r
+ // expected-warning{{attribute 'aligned' is ignored, place it after "union" to apply attribute to type declaration}} \r
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) enum D {D}; // expected-warning{{attribute 'visibility' is ignored, place it after "enum" to apply attribute to type declaration}} \\r
+ // expected-warning{{attribute 'aligned' is ignored, place it after "enum" to apply attribute to type declaration}}\r
+}\r
+\r
+namespace test2 {\r
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) class A {} a;\r
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) struct B {} b;\r
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) union C {} c;\r
+ __attribute__((visibility("hidden"))) __attribute__((aligned)) enum D {D} d;\r
+}\r