[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