[cfe-commits] [patch] PR10127/N3031 supporting decltype in nested-namespace-specifiers

David Blaikie dblaikie at gmail.com
Mon Dec 5 14:11:11 PST 2011


On Mon, Dec 5, 2011 at 2:58 PM, Johannes Schaub
<schaub.johannes at googlemail.com> wrote:
> Douglas Gregor wrote:
>
>>
>> On Nov 14, 2011, at 8:10 AM, David Blaikie wrote:
>>
>>>> Some comments follow…
>>>
>>> Thanks for the feedback.
>>>
>>>> Index: include/clang/Basic/TokenKinds.def
>>>> ===================================================================
>>>> --- include/clang/Basic/TokenKinds.def  (revision 143902)
>>>> +++ include/clang/Basic/TokenKinds.def  (working copy)
>>>> @@ -559,6 +559,8 @@
>>>>                          // function template specialization (not a
>>>>                          type), // e.g., "std::swap<int>"
>>>>  ANNOTATION(primary_expr) // annotation for a primary expression
>>>> +ANNOTATION(decltype)     // annotation for a decltype expression,
>>>> +                         // e.g., "decltype(foo.bar())"
>>>>
>>>>  // Annotation for #pragma unused(...)
>>>>  // For each argument inside the parentheses the pragma handler will
>>>>  produce
>>>>
>>>> Did you consider using annot_typename for this? I ask because
>>>> annot_typename handles general types (including decltype), and is
>>>> already well-supported throughout the parser. It looks like you've
>>>> checked for annot_decltype in several places, but others (such as the
>>>> tentative parser) would be confused by this annotation token.
>>>
>>> No, I hadn't considered that - but at first blush I'd be concerned
>>> that this might end up being /too/ permissive, but I'll have a go
>>> mocking it up that way, it'll probably be tidier but I won't be sure
>>> what other scenarios might be accidentally accepted.
>>
>> I'm fine with keeping annot_decltype. It's super-specific, so just make
>> sure you're auditing the various places where we have to deal with, e.g.,
>> the 'decltype' keyword or the annot_typename token so you catch all of the
>> places 'decltype' can show up.
>>
>>>> Index: include/clang/Basic/DiagnosticSemaKinds.td
>>>> ===================================================================
>>>> --- include/clang/Basic/DiagnosticSemaKinds.td  (revision 143902)
>>>> +++ include/clang/Basic/DiagnosticSemaKinds.td  (working copy)
>>>> @@ -3957,6 +3957,7 @@
>>>>   "conversion function from %0 to %1 invokes a deleted function">;
>>>>
>>>>  def err_expected_class_or_namespace : Error<"expected a class or
>>>>  namespace">;
>>>> +def err_expected_class : Error<"expected a decltype of a class">;
>>>>  def err_missing_qualified_for_redecl : Error<
>>>>   "must qualify the name %0 to declare %q1 in this scope">;
>>>>  def err_invalid_declarator_scope : Error<
>>>>
>>>> Could you provide a better error message here? Something that, at the
>>>> very least, tells the user what the actual type is? Also, enum types
>>>> would also be fine in C++11, so the diagnostic isn't quite accurate.
>>>
>>> Sure - I was going off the (admittedly rather vague) existing message
>>> above. I've rephrased this to, for example:
>>>
>>>    'decltype(int())' (aka 'int') is not a namespace, class, or scoped
>>> enumeration
>>>
>>> I think it'd be helpful to use this diagnostic for the existing case
>>> above. It comes up most easily if you have a typedef that resolves to
>>> int for example:
>>>
>>>    namespace foo { typedef int bar; }
>>>
>>>    foo::bar::baz i; // "expected class or namespace" (^ points to the
>>> 'b' in 'bar')
>>>
>>> & you don't get told what foo::bar is. Though my version is a bit more
>>> verbose.
>>
>> It's definitely an improvement. We only want that 'or scoped enumeration'
>> bit if we're in C++11.
>>
>
> Wanna drop a little comment on this - the diagnostic fools users that a
> scoped enumeration is required to use "::", but unscoped enumerations ("enum
> foo { bar }") can be used likewise with the scope operator.

Actually that's (one of) the point - unscoped enumerations cannot be
used in the same way:

enum foo { bar };
foo f = foo::bar; // GCC: "foo is not a class or namespace", Clang:
"Expected a class or namespace" (to be revised)

They can be used at the end of (technically 'after' - the NSS is the
thing before the final name) a nested name specifier, as in:

::foo f;

But not in the middle - though perhaps that's what you mean, that it's
really the attempt to scope within the name (the :: after 'foo', not
before) that is the problem & perhaps that isn't clear from the
message/pointer.

> Just my two cents, but I guess since you already figured out an IMO better
> wording ("lookup into a type without members"), this note is just for the
> record.

Yeah, I'm still not sure what the ideal wording is, really.

- David




More information about the cfe-commits mailing list