diff options
author | Erich Keane <erich.keane@intel.com> | 2017-09-29 21:06:00 +0000 |
---|---|---|
committer | Erich Keane <erich.keane@intel.com> | 2017-09-29 21:06:00 +0000 |
commit | 3e08f66bb0f46d1065671afb6357d9162213606e (patch) | |
tree | 735c6f985fd3a187d8ebaf2035689ff7bed77e75 /clang/lib/AST/DeclCXX.cpp | |
parent | 345187338ed789c456f80a27d32620971dbe8871 (diff) | |
download | bcm5719-llvm-3e08f66bb0f46d1065671afb6357d9162213606e.tar.gz bcm5719-llvm-3e08f66bb0f46d1065671afb6357d9162213606e.zip |
[Sema] Correct IUnknown to support Unknwnbase.h Header.
Apparently, the MSVC SDK has a strange implementation that
causes a number of implicit functions as well as a template member
function of the IUnknown type. This patch allows these as InterfaceLike
types as well.
Additionally, it corrects the behavior where extern-C++ wrapped around an
Interface-Like type would permit an interface-like type to exist in a namespace.
Differential Revision: https://reviews.llvm.org/D38303
llvm-svn: 314557
Diffstat (limited to 'clang/lib/AST/DeclCXX.cpp')
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index e85ab418514..a9759b4c0a2 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -1470,6 +1470,15 @@ bool CXXRecordDecl::isAnyDestructorNoReturn() const { return false; } +static bool isDeclContextInNamespace(const DeclContext *DC) { + while (!DC->isTranslationUnit()) { + if (DC->isNamespace()) + return true; + DC = DC->getParent(); + } + return false; +} + bool CXXRecordDecl::isInterfaceLike() const { assert(hasDefinition() && "checking for interface-like without a definition"); // All __interfaces are inheritently interface-like. @@ -1486,13 +1495,16 @@ bool CXXRecordDecl::isInterfaceLike() const { // No interface-like type can have a method with a definition. for (const auto *const Method : methods()) - if (Method->isDefined()) + if (Method->isDefined() && !Method->isImplicit()) return false; // Check "Special" types. const auto *Uuid = getAttr<UuidAttr>(); - if (Uuid && isStruct() && (getDeclContext()->isTranslationUnit() || - getDeclContext()->isExternCXXContext()) && + // MS SDK declares IUnknown/IDispatch both in the root of a TU, or in an + // extern C++ block directly in the TU. These are only valid if in one + // of these two situations. + if (Uuid && isStruct() && !getDeclContext()->isExternCContext() && + !isDeclContextInNamespace(getDeclContext()) && ((getName() == "IUnknown" && Uuid->getGuid() == "00000000-0000-0000-C000-000000000046") || (getName() == "IDispatch" && |