<div class="gmail_quote">On Fri, Dec 10, 2010 at 7:18 AM, Douglas Gregor <span dir="ltr"><<a href="mailto:dgregor@apple.com">dgregor@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><div></div><div class="h5"><br>
On Dec 10, 2010, at 12:18 AM, Enea Zaffanella wrote:<br>
<br>
> Il 09/12/2010 16:08, Douglas Gregor ha scritto:<br>
>><br>
>> On Dec 8, 2010, at 12:02 PM, Enea Zaffanella wrote:<br>
>><br>
>>> Il 07/12/2010 18:36, Douglas Gregor ha scritto:<br>
>>>><br>
>>>> On Dec 7, 2010, at 6:39 AM, Enea Zaffanella wrote:<br>
>>>><br>
>>>>> Hello.<br>
>>>>><br>
>>>>> We noticed some time ago that the AST representation used in clang does<br>
>>>>> not allow for the representation of those pairs of parentheses that can<br>
>>>>> occur inside a syntactic type. For instance, the following C code:<br>
>>>>><br>
>>>>> void ((((*fun_ptr))))(void);<br>
>>>>> int (*(int_arr_ptr))[15];<br>
>>>>> void (((*((*fun_ptr_arr_ptr)[10]))))(int, int);<br>
>>>>> int ((a));<br>
>>>>><br>
>>>>> is printed (using -ast-print) as follows<br>
>>>>><br>
>>>>> void (*fun_ptr)(void);<br>
>>>>> int (*int_arr_ptr)[15];<br>
>>>>> void (*(*fun_ptr_arr_ptr)[10])(int, int);<br>
>>>>> int a;<br>
>>>>><br>
>>>>> The printed parentheses are not directly represented in the AST: they<br>
>>>>> are inserted by the pretty printer (to respect precedence).<br>
>>>>><br>
>>>>> Are there plans to extend the AST in order to faithfully represent the<br>
>>>>> code above?<br>
>>>><br>
>>>> Not that I know of.<br>
>>>><br>
>>>>> To our eyes, it seems that the Type hierarchy should be enriched by<br>
>>>>> adding a ParenType derived class (similar to the ParenExpr class for the<br>
>>>>> Expr hierarchy). A ParenType would always be a non-canonical type and<br>
>>>>> the corresponding ParenTypeLoc would provide locations for the two<br>
>>>>> parentheses. At the parser level, we would have another kind of<br>
>>>>> DeclaratorChunk.<br>
>>>>><br>
>>>>> Would this approach make sense?<br>
>>>><br>
>>>> Yes, this approach makes sense to me.<br>
>>>><br>
>>>>    - Doug<br>
>>><br>
>>> OK, here is attached a patch along the sketch mentioned above.<br>
>>> It passes all clang tests but a single one.<br>
>><br>
>> Looks great, with one comment below about the failing test.<br>
>><br>
>>> The failing test is something related to ObjC, on which I have very<br>
>>> little confidence. Apparently, it seems that we should adjust the<br>
>>> expected output, which currently is as follows:<br>
>>><br>
>>> FunctionDecl:{ResultType void}{TypedText f}{LeftParen (}{Placeholder<br>
>>> ^int(int x, int y)block}{RightParen )} (50)<br>
>>><br>
>>> whereas we now obtain an extra pair of parentheses:<br>
>>><br>
>>> FunctionDecl:{ResultType void}{TypedText f}{LeftParen (}{Placeholder int<br>
>>> (^)(int, int)}{RightParen )} (50)<br>
>><br>
>> This probably just means that we need to look through ParenTypeLocs within the FormatFunctionParameter routine in SemaCodeComplete.cpp.<br>
><br>
> Right, we were missing that source file.<br>
> Now even that one test passes.<br>
<br>
</div></div>Great!<br>
<div class="im"><br>
>>> We look forward for suggestions/corrections/etc.<br>
>><br>
>> How many parenthesized types do you see in a typical .c or .cpp file?<br>
>><br>
>>      - Doug<br>
><br>
> Well, of course the answer will depend on the meaning of "typical", but<br>
> anyway my guess is that they should be very few. Is it just curiosity or<br>
> are you really worried about the memory space impact?<br>
<br>
<br>
</div>Just curious; you can go ahead and commit this. Parenthesized types aren't common enough to worry about.<br></blockquote><div><br></div><div>Hah! So you say. I'll see you that overconfidence and raise you a testcase from Boost's boost/math/special_functions/fpclassify.hpp:</div>
<div><br></div><div><div>% cat t.cc</div><div>template <typename T> inline bool (f)(T x) {</div><div>  return false;</div><div>}</div><div><br></div><div>template <typename T> inline T g(const T& v) {</div>
<div>  if (!(::f)(v))</div><div>    return 0;</div><div>  return v;</div><div>}</div><div><br></div><div>void test() {</div><div>  int i;</div><div>  g(i);</div><div>}</div><div><br></div><div>Crashes after this patch. I'm looking into it.</div>
</div></div>