Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -1618,7 +1618,7 @@ def Uuid : InheritableAttr { let Spellings = [Declspec<"uuid">, Microsoft<"uuid">]; let Args = [StringArgument<"Guid">]; -// let Subjects = SubjectList<[CXXRecord]>; + let Subjects = SubjectList<[CXXRecord, Enum], WarnDiag, "ExpectedEnumOrClass">; let LangOpts = [MicrosoftExt, Borland]; let Documentation = [Undocumented]; } Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -2633,7 +2633,8 @@ "|variables, enums, fields and typedefs" "|functions, methods, enums, and classes" "|structs, classes, variables, functions, and inline namespaces" - "|variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members}1">, + "|variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members" + "|classes, enums}1">, InGroup; def err_attribute_wrong_decl_type : Error; def warn_type_attribute_wrong_type : Warning< Index: include/clang/Sema/AttributeList.h =================================================================== --- include/clang/Sema/AttributeList.h +++ include/clang/Sema/AttributeList.h @@ -924,7 +924,8 @@ ExpectedVariableEnumFieldOrTypedef, ExpectedFunctionMethodEnumOrClass, ExpectedStructClassVariableFunctionOrInlineNamespace, - ExpectedForMaybeUnused + ExpectedForMaybeUnused, + ExpectedEnumOrClass }; } // end namespace clang Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -4666,9 +4666,9 @@ return; } - if (!isa(D)) { + if (!(isa(D) || isa(D))) { S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) - << Attr.getName() << ExpectedClass; + << Attr.getName() << ExpectedEnumOrClass; return; } Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -520,7 +520,7 @@ else if (QT->isArrayType()) Ty = Ty->getBaseElementTypeUnsafe(); - const auto *RD = Ty->getAsCXXRecordDecl(); + const auto *RD = Ty->getAsTagDecl(); if (!RD) return; Index: test/Parser/MicrosoftExtensions.cpp =================================================================== --- test/Parser/MicrosoftExtensions.cpp +++ test/Parser/MicrosoftExtensions.cpp @@ -65,6 +65,10 @@ struct struct_with_uuid2 {} ; +enum __declspec(uuid("000000A0-0000-0000-C000-000000000046")) +enum_with_uuid { }; +enum enum_without_uuid { }; + int uuid_sema_test() { struct_with_uuid var_with_uuid[1]; @@ -81,6 +85,15 @@ __uuidof(const struct_with_uuid[1][1]); __uuidof(const struct_with_uuid*[1][1]); // expected-error {{cannot call operator __uuidof on a type with no GUID}} + __uuidof(enum_with_uuid); + __uuidof(enum_without_uuid); // expected-error {{cannot call operator __uuidof on a type with no GUID}} + __uuidof(enum_with_uuid*); + __uuidof(enum_without_uuid*); // expected-error {{cannot call operator __uuidof on a type with no GUID}} + __uuidof(enum_with_uuid[1]); + __uuidof(enum_with_uuid*[1]); // expected-error {{cannot call operator __uuidof on a type with no GUID}} + __uuidof(const enum_with_uuid[1][1]); + __uuidof(const enum_with_uuid*[1][1]); // expected-error {{cannot call operator __uuidof on a type with no GUID}} + __uuidof(var_with_uuid); __uuidof(var_without_uuid);// expected-error {{cannot call operator __uuidof on a type with no GUID}} __uuidof(var_with_uuid[1]);