[cfe-commits] [PATCH][MS][Review request] - Optional template keyword in Microsoft mode.
Francois Pichet
pichet2000 at gmail.com
Sun Mar 27 12:48:00 PDT 2011
On Sun, Mar 27, 2011 at 6:09 AM, Douglas Gregor <dgregor at apple.com> wrote:
>
> On Mar 24, 2011, at 5:47 AM, Francois Pichet wrote:
>
>> Hi,
>>
>> Small parser hack to be able to parse type dependent template name
>> without the "template" keyword in Microsoft mode.
>> This patch fixes about a dozen compile errors when parsing MSVC STL
>> headers with clang.
>>
>> For example:
>> =========
>> template <class A>
>> class C1 {
>> public:
>> template <int B>
>> class Iterator {
>> };
>> };
>>
>> template<class T>
>> class C2 {
>> // template is optional in microsoft mode.
>> typename C1<T>:: /*template*/ Iterator<0> Mypos;
>> };
>>
>> ok to commit?
>
> This particular parser recovery would be great, not just for Microsoft mode but in general. So, I'd like to see this handled by making the parser recover well from a missing 'template' keyword (diagnostic + Fix-It) and then either downgrading the diagnostic (to a warning) or omitting it entirely for Microsoft mode.
>
> + // Microsoft mode parser hack to be able to parse type dependent
> + // template name without the "template" keyword.
> + bool IsImplicitTemplate = getLang().Microsoft && IsTypename &&
> + Tok.is(tok::identifier) &&
> + NextToken().is(tok::less) &&
> + (getCurScope()->getFlags() & Scope::DeclScope) &&
> + (HasScopeSpecifier || ObjectType);
> +
> // nested-name-specifier:
> // nested-name-specifier 'template'[opt] simple-template-id '::'
>
> // Parse the optional 'template' keyword, then make sure we have
> // 'identifier <' after it.
> - if (Tok.is(tok::kw_template)) {
> + if (Tok.is(tok::kw_template) || IsImplicitTemplate) {
> // If we don't have a scope specifier or an object type, this isn't a
> // nested-name-specifier, since they aren't allowed to start with
> // 'template'.
>
> I think this is the wrong place to perform the recovery, because we're forcing Clang to go down the dependent template-name path even in cases where we might be looking at a non-dependent template name.
>
> Instead, I suggest improving recovery down in the identifier case, by improving the heuristics for the current diagnostic that inserts a dependent 'template' keyword:
>
> if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) &&
> IsTemplateArgumentList(1)) {
> // We have something like t::getAs<T>, where getAs is a
> // member of an unknown specialization. However, this will only
> // parse correctly as a template, so suggest the keyword 'template'
> // before 'getAs' and treat this as a dependent template name.
> Diag(Tok.getLocation(), diag::err_missing_dependent_template_keyword)
> << II.getName()
> << FixItHint::CreateInsertion(Tok.getLocation(), "template ");
>
> It might be as easy as turning that last condition into "(IsTypename || IsTemplateArgumentList(1))".
>
Ok this works fine, committed in 128387
More information about the cfe-commits
mailing list