[PATCH] D37308: Interface class with uuid base record

Zahira Ammarguellat via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 13 14:55:22 PDT 2017


zahiraam updated this revision to Diff 115125.
zahiraam added a comment.

Hi have made all the changes requested.


https://reviews.llvm.org/D37308

Files:
  lib/Sema/SemaDeclCXX.cpp


Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -2373,6 +2373,40 @@
   return true;
 }
 
+/// \brief Tests if RD is a public interface.
+static bool IsDeclPublicInterface(const CXXRecordDecl *RD,
+                                  AccessSpecifier spec) {
+  return RD->isInterface() && spec == AS_public;
+}
+
+/// \brief Test if record is a uuid for IUnknown.
+/// This is an MS SDK specific type that has a special
+/// behavior in the CL compiler.
+static bool IsIUnknownType(const CXXRecordDecl *RD) {
+  const auto *Uuid = RD->getAttr<UuidAttr>();
+
+  return Uuid && RD->isStruct()  && RD->isEmpty() &&
+         RD->getDeclContext()->isTranslationUnit() &&
+         RD->getName() == "IUnknown" &&
+         Uuid->getGuid() =="00000000-0000-0000-C000-000000000046";
+}
+
+/// \brief Test if RD or its inherited bases is an IUnknown type.
+static bool IsOrInheritsFromIUnknown(const CXXRecordDecl *RD) {
+  bool IsUnknown = IsIUnknownType(RD);
+  for (CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(),
+                                                BaseEnd = RD->bases_end();
+       Base != BaseEnd; ++Base) {
+   CXXRecordDecl *BaseChild = Base->getType()->getAsCXXRecordDecl();
+   
+   return IsUnknown ||
+          IsOrInheritsFromIUnknown(BaseChild) ||
+          (RD->getNumBases() > 1) &&
+          IsOrInheritsFromIUnknown((CXXRecordDecl*) BaseChild->getNextDeclInContext());
+  }
+  return IsUnknown;
+}
+
 /// Use small set to collect indirect bases.  As this is only used
 /// locally, there's no need to abstract the small size parameter.
 typedef llvm::SmallPtrSet<QualType, 4> IndirectBaseSet;
@@ -2450,10 +2484,10 @@
       if (const RecordType *Record = NewBaseType->getAs<RecordType>()) {
         const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
         if (Class->isInterface() &&
-              (!RD->isInterface() ||
-               KnownBase->getAccessSpecifier() != AS_public)) {
-          // The Microsoft extension __interface does not permit bases that
-          // are not themselves public interfaces.
+            // The Microsoft extension __interface does not permit bases that
+            // are not themselves public interfaces.
+            !IsDeclPublicInterface(RD, KnownBase->getAccessSpecifier()) &&
+            !IsOrInheritsFromIUnknown(RD)) {
           Diag(KnownBase->getLocStart(), diag::err_invalid_base_in_interface)
             << getRecordDiagFromTagKind(RD->getTagKind()) << RD->getName()
             << RD->getSourceRange();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D37308.115125.patch
Type: text/x-patch
Size: 2639 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170913/bc2ce0d4/attachment.bin>


More information about the cfe-commits mailing list