puetzk created this revision.
puetzk added a subscriber: cfe-commits.
puetzk set the repository for this revision to rL LLVM.

Although not specifically mentioned in the documentation, MSVC accepts 
__uuidof(…) and declspec(uuid("…")) attributes on enumeration types in addition 
to structs/classes. This is meaningful, as such types *do* have associated 
UUIDs in ActiveX typelibs, and such attributes are included by default in the 
wrappers generated by their #import construct, so they are not particularly 
unusual.

clang currently rejects the declspec with a –Wignored-attributes warning, and 
errors on __uuidof() with “cannot call operator __uuidof on a type with no 
GUID” (because it rejected the uuid attribute, and therefore finds no value). 
This is causing problems for us while trying to use clang-tidy on a codebase 
that makes heavy use of ActiveX.

I believe I have found the relevant places to add this functionality, this 
patch adds this case to clang’s implementation of these MS extensions. 
patch is against r285994 (or actually the git mirror 80464680ce).

Both include an update to test/Parser/MicrosoftExtensions.cpp to exercise the 
new functionality.

This is my first time contributing to LLVM, so if I’ve missed anything else 
needed to prepare this for review just let me know!

__uuidof: https://msdn.microsoft.com/en-us/library/zaah6a61.aspx
declspec(uuid("…")): https://msdn.microsoft.com/en-us/library/3b6wkewa.aspx
#import: https://msdn.microsoft.com/en-us/library/8etzzkb6.aspx


Repository:
  rL LLVM

https://reviews.llvm.org/D26846

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/AttributeList.h
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaExprCXX.cpp
  test/Parser/MicrosoftExtensions.cpp

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]);
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: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -4666,9 +4666,9 @@
     return;
   }
 
-  if (!isa<CXXRecordDecl>(D)) {
+  if (!(isa<CXXRecordDecl>(D) || isa<EnumDecl>(D))) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedClass;
+      << Attr.getName() << ExpectedEnumOrClass;
     return;
   }
 
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: 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<IgnoredAttributes>;
 def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
 def warn_type_attribute_wrong_type : Warning<
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];
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to