List of future Microsoft extensions work

Here is the list of the 5 missing features (Microsoft extensions) that
currently prevent clang from parsing the default MFC and ATL wizard
generated projects (MSVC 2010).

- some missing typename disambiguation
- allowing reference in union.
- Microsoft resolves template default arguments at instantiation time.
(clang will have to late parse them)
- 1 missing case of "lookup into dependent base classes". Specifically
for template member functions.
- Allowing the creating of pointer to member using
     a = static_cast<PTF_TYPE>(Member) (clang requires &class_name::Member)

I'll work on adding these to clang.

Thanks for working on all this :).

- Michael Spencer

Hi Francois,

I have been working on Clang as part of the Parfait project at Oracle Labs. My work on the compiler has focused on adding compatibility support for the Intel C/C++ and Oracle Solaris Studio dialects of C and C++. Both of these also require look-up into dependent base classes. The Oracle compiler specifically requires the look-up into base classes algorithm to handle looking up typedefs and I think the same is true for ICC. For example, the following snippet is legal in Oracle Solaris Studio:

template<class T>
class Base {
public:
   typedef int II;
};

template<class T>
class Derived : public Base<T> {
public:
   II operation();
};

I began work to implement support for this around the time you were committing your initial patches for look-up in dependent base classes earlier this year, but because I needed this type look-up to work, I ended up writing my own implementation which involved extending the look-up algorithms in Clang. I think this approach may be more general and clearer than the special casing of look-ups that you have had to do and I thought I might outline how I did the look-up to see what you and others think.

Look-up of non-types:
Perform the look-up as normal, but if the look-up in the base classes fails to find the symbol and there are any dependent bases, then return NotFoundInCurrentInstantiation rather than NotFound. This has the effect of delaying the type checking for that symbol until instantiation time at which point none of the bases will be dependent and the look-up can either find or not find the symbol as appropriate. This does defer some error generation compared to normal Clang, but the error generation becomes more consistent with that the compilers being emulated.

Look-up of types:
The look-up of types is a bit more tricky because the type returned by the look-up needs to be in the correct form for the template tree transformer to create the correct actual type during template instantiation, unlike the non-type symbol case where we can defer and the look-up is performed again post-instantiation. To achieve this I modified the look-up methods to include a flag to indicate if the look-up should enter dependent bases. When the flag is set and a dependent base if found, the algorithm enters the uninstantiated template declaration looking for the appropriate symbol. While doing this special traversal, the algorithm records the path followed to arrive at the symbol. If the look-up succeeds I use this sequence of base classes to construct a nested name specifier and I build either a DependentNameType or a TypenameType depending on if the final result is dependent or not. For example

template<class T>
class Base {
public:
   typedef T II;
};

template<class T>
class Derived : public Base<T> {
   II operation();
}
In this above case, the look-up algorithm will produce a DependentNameType which represents the type Base<T>::T which will result in the correct type for operation being computed during instantiation.

class Baz {
public:
   typedef int II;
};

template<class T>
class Base : public Baz {
};

template<class T>
class Derived : public Base<T> {
public:
   II operation();
};
This above results in a TypenameType of the form Base<T>::Baz::II which boils down to int prior to template instantiation so the tree transformer does not have to worry about transforming the type.

If the look-up returns an ambiguity then the program is incorrect because without the scope specifier even the compilers which do allow look-up into dependent base types cannot resolve the type and so the programmer needs to supply the fully qualified name. One of the nice things I have found about this approach is that I can produce an error or warning message showing the programmer the scope specifier they need to put on their type to make it standards compliant which would be very helpful to people trying to port from one of the dialects that support this feature to a more standards compliant dialect.

I have this change implemented in Clang 2.9 and, with permission from my management here at Oracle, I should be able to port it to the current version of Clang and contribute it back to the community if it is wanted. Overall, the change is relatively few lines of code and is confined to the look-up algorithms - the rest of the code does not need to worry about the style of template handling being used which seems a bit neater to me.

Thanks for all your work on the Microsoft support, it made adding support for these other compilers that bit easier. I look forward to hearing the community's thoughts on this alternative approach.

Kind regards,
Andrew

Hi, sure, you can post your patch to cfe-commit and we can discuss there.
My patches don't handle all cases of of lookup into dependent bases
but deal with most cases found in MFC and ATL code. It would be great
if your solution is more general.

They have their own name mangling and object mapping/layout as well as exception handling.

If you want to interoperate with prebuilt libraries you would have to do that also.

Back in the day there was a developers kit for non microsoft compiler vendors.