r314557 - [Sema] Correct IUnknown to support Unknwnbase.h Header.
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 29 14:06:01 PDT 2017
Author: erichkeane
Date: Fri Sep 29 14:06:00 2017
New Revision: 314557
URL: http://llvm.org/viewvc/llvm-project?rev=314557&view=rev
Log:
[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
Added:
cfe/trunk/test/SemaCXX/ms-iunknown-template-function.cpp (with props)
Modified:
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/test/SemaCXX/ms-iunknown.cpp
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=314557&r1=314556&r2=314557&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Fri Sep 29 14:06:00 2017
@@ -1470,6 +1470,15 @@ bool CXXRecordDecl::isAnyDestructorNoRet
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() co
// 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" &&
Added: cfe/trunk/test/SemaCXX/ms-iunknown-template-function.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/ms-iunknown-template-function.cpp?rev=314557&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/ms-iunknown-template-function.cpp (added)
+++ cfe/trunk/test/SemaCXX/ms-iunknown-template-function.cpp Fri Sep 29 14:06:00 2017
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s
+typedef long HRESULT;
+typedef unsigned long ULONG;
+typedef struct _GUID {
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[8];
+} GUID;
+typedef GUID IID;
+
+// remove stdcall, since the warnings have nothing to do with
+// what is being tested.
+#define __stdcall
+
+extern "C" {
+extern "C++" {
+// expected-warning at +1 {{__declspec attribute 'novtable'}}
+struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable)
+ IUnknown {
+public:
+ virtual HRESULT __stdcall QueryInterface(
+ const IID &riid,
+ void **ppvObject) = 0;
+
+ virtual ULONG __stdcall AddRef(void) = 0;
+
+ virtual ULONG __stdcall Release(void) = 0;
+
+ template <class Q>
+ HRESULT __stdcall QueryInterface(Q **pp) {
+ return QueryInterface(__uuidof(Q), (void **)pp);
+ }
+};
+}
+}
+
+__interface ISfFileIOPropertyPage : public IUnknown{};
+
Propchange: cfe/trunk/test/SemaCXX/ms-iunknown-template-function.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/SemaCXX/ms-iunknown-template-function.cpp
------------------------------------------------------------------------------
svn:keywords = Author Date Id Rev URL
Propchange: cfe/trunk/test/SemaCXX/ms-iunknown-template-function.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: cfe/trunk/test/SemaCXX/ms-iunknown.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/ms-iunknown.cpp?rev=314557&r1=314556&r2=314557&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/ms-iunknown.cpp (original)
+++ cfe/trunk/test/SemaCXX/ms-iunknown.cpp Fri Sep 29 14:06:00 2017
@@ -2,7 +2,11 @@
extern "C++" struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown {
void foo();
+ // Definitions aren't allowed, unless they are a template.
+ template<typename T>
+ void bar(T t){}
};
+
struct IPropertyPageBase : public IUnknown {};
struct IPropertyPage : public IPropertyPageBase {};
__interface ISfFileIOPropertyPage : public IPropertyPage {};
@@ -11,10 +15,17 @@ __interface ISfFileIOPropertyPage : publ
namespace NS {
struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown {};
// expected-error at +1 {{interface type cannot inherit from}}
- __interface IPropertyPageBase : public IUnknown {};
+ __interface IPropertyPageBase : public IUnknown {};
}
+
+namespace NS2 {
+extern "C++" struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown {};
+// expected-error at +1 {{interface type cannot inherit from}}
+__interface IPropertyPageBase : public IUnknown{};
+}
+
// expected-error at +1 {{interface type cannot inherit from}}
-__interface IPropertyPageBase2 : public NS::IUnknown {};
+__interface IPropertyPageBase2 : public NS::IUnknown {};
__interface temp_iface {};
struct bad_base : temp_iface {};
@@ -32,8 +43,8 @@ __interface PropertyPage : public Page4
struct Page5 : public Page3, Page4{};
// expected-error at +1 {{interface type cannot inherit from}}
-__interface PropertyPage2 : public Page5 {};
+__interface PropertyPage2 : public Page5 {};
__interface IF1 {};
-__interface PP : IUnknown, IF1{};
+__interface PP : IUnknown, IF1{};
__interface PP2 : PP, Page3, Page4{};
More information about the cfe-commits
mailing list