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]>; let LangOpts = [MicrosoftExt, Borland]; let Documentation = [Undocumented]; } Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -2641,7 +2641,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 and enumerations}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 @@ -925,7 +925,8 @@ ExpectedVariableEnumFieldOrTypedef, ExpectedFunctionMethodEnumOrClass, ExpectedStructClassVariableFunctionOrInlineNamespace, - ExpectedForMaybeUnused + ExpectedForMaybeUnused, + ExpectedEnumOrClass }; } // end namespace clang Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -4666,12 +4666,6 @@ return; } - if (!isa(D)) { - S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) - << Attr.getName() << ExpectedClass; - return; - } - StringRef StrRef; SourceLocation LiteralLoc; if (!S.checkStringLiteralArgumentAttr(Attr, 0, StrRef, &LiteralLoc)) Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -520,17 +520,17 @@ else if (QT->isArrayType()) Ty = Ty->getBaseElementTypeUnsafe(); - const auto *RD = Ty->getAsCXXRecordDecl(); - if (!RD) + const auto *TD = Ty->getAsTagDecl(); + if (!TD) return; - if (const auto *Uuid = RD->getMostRecentDecl()->getAttr()) { + if (const auto *Uuid = TD->getMostRecentDecl()->getAttr()) { UuidAttrs.insert(Uuid); return; } // __uuidof can grab UUIDs from template arguments. - if (const auto *CTSD = dyn_cast(RD)) { + if (const auto *CTSD = dyn_cast(TD)) { const TemplateArgumentList &TAL = CTSD->getTemplateArgs(); for (const TemplateArgument &TA : TAL.asArray()) { const UuidAttr *UuidForTA = nullptr; Index: test/Parser/MicrosoftExtensions.cpp =================================================================== --- test/Parser/MicrosoftExtensions.cpp +++ test/Parser/MicrosoftExtensions.cpp @@ -65,6 +65,12 @@ struct struct_with_uuid2 {} ; +enum __declspec(uuid("000000A0-0000-0000-C000-000000000046")) +enum_with_uuid { }; +enum enum_without_uuid { }; + +int __declspec(uuid("000000A0-0000-0000-C000-000000000046")) inappropriate_uuid; // expected-warning {{'uuid' attribute only applies to classes and enumerations}} + int uuid_sema_test() { struct_with_uuid var_with_uuid[1]; @@ -81,6 +87,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]); Index: utils/TableGen/ClangAttrEmitter.cpp =================================================================== --- utils/TableGen/ClangAttrEmitter.cpp +++ utils/TableGen/ClangAttrEmitter.cpp @@ -2681,6 +2681,7 @@ case ObjCProtocol | ObjCInterface: return "ExpectedObjectiveCInterfaceOrProtocol"; case Field | Var: return "ExpectedFieldOrGlobalVar"; + case Class | Enum: return "ExpectedEnumOrClass"; } PrintFatalError(S.getLoc(),