[cfe-dev] List of future Microsoft extensions work
Andrew Craik
andrew.craik at oracle.com
Wed Dec 14 21:38:06 PST 2011
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
On 13-Dec-11 10:11, Francois Pichet wrote:
> 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.
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
More information about the cfe-dev
mailing list