summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/DeclCXX.cpp
diff options
context:
space:
mode:
authorErich Keane <erich.keane@intel.com>2017-09-29 21:06:00 +0000
committerErich Keane <erich.keane@intel.com>2017-09-29 21:06:00 +0000
commit3e08f66bb0f46d1065671afb6357d9162213606e (patch)
tree735c6f985fd3a187d8ebaf2035689ff7bed77e75 /clang/lib/AST/DeclCXX.cpp
parent345187338ed789c456f80a27d32620971dbe8871 (diff)
downloadbcm5719-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.cpp18
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" &&
OpenPOWER on IntegriCloud