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/test/SemaCXX | |
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/test/SemaCXX')
-rw-r--r-- | clang/test/SemaCXX/ms-iunknown-template-function.cpp | 39 | ||||
-rw-r--r-- | clang/test/SemaCXX/ms-iunknown.cpp | 19 |
2 files changed, 54 insertions, 4 deletions
diff --git a/clang/test/SemaCXX/ms-iunknown-template-function.cpp b/clang/test/SemaCXX/ms-iunknown-template-function.cpp new file mode 100644 index 00000000000..dc192238fbd --- /dev/null +++ b/clang/test/SemaCXX/ms-iunknown-template-function.cpp @@ -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@+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{}; + diff --git a/clang/test/SemaCXX/ms-iunknown.cpp b/clang/test/SemaCXX/ms-iunknown.cpp index f73864d43fb..df761d56a80 100644 --- a/clang/test/SemaCXX/ms-iunknown.cpp +++ b/clang/test/SemaCXX/ms-iunknown.cpp @@ -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 : public IPropertyPage {}; namespace NS { struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown {}; // expected-error@+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@+1 {{interface type cannot inherit from}} +__interface IPropertyPageBase : public IUnknown{}; +} + // expected-error@+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@+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{}; |