Goal: Clang should be able to parse the following code with '-fms-compatibility' because MSVC allows using the 'enum' specifier for typedef'd enums:
typedef enum { First, Second } MyEnum; void func() { enum MyEnum foo; }
Today the code above produces the following compile error:
<source>:9:7: error: typedef 'MyEnum' cannot be referenced with a enum specifier enum MyEnum foo; ^ <source>:5:3: note: declared here } MyEnum; ^
The reason why this change is desired in Clang is because the MSVC tools 'mktyplib' and 'midl' produce C++ code which uses the 'enum' specifier in such a way. Here is a small repro:
MyEnum.idl:
[ uuid(da2889bf-6173-4c1c-a23d-52ad85fc91ca) ] library MyEnumLib { typedef enum { X } MyEnum; };
Application.idl:
[ uuid(4d0cc96f-3258-46f7-98bf-6654c1d027c5) ] library ApplicationLib { importlib("MyEnum.tlb"); [ uuid(6ac4c3d7-15c7-40c7-8b64-60459e29680b) ] interface ApplicationInterface : IDispatch { [ id(66), propget ] HRESULT Foo([out, retval] enum MyEnum* Foo); [ id(66), propput ] HRESULT Foo([in] enum MyEnum Foo); }; };
Use the following commands to build:
mktyplib /win32 /cpp_cmd cl.exe /cpp_opt /E /tlb MyEnum.tlb /h MyEnum.h MyEnum.idl midl -h Application.h -iid Application.c -tlb Application.tlb /cpp_cmd cl.exe Application.idl
This produces Application.h with the following snippet (note the usage of the 'enum' specifier):
MIDL_INTERFACE("6ac4c3d7-15c7-40c7-8b64-60459e29680b") ApplicationInterface : public IDispatch { public: virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Foo( /* [retval][out] */ enum /* external definition not present */ MyEnum *Foo) = 0; virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Foo( /* [in] */ enum /* external definition not present */ MyEnum Foo) = 0; };
Note that the 'mktyplib' tool is deprecated now but it's used for building some code here at Microsoft, and probably other legacy build scenarios in the industry as well.
Our coding style does not parenthesize == within &&.