[cfe-dev] Recovering the spelling of a typedef

Philippe Canal via cfe-dev cfe-dev at lists.llvm.org
Sat Jul 30 08:06:02 PDT 2016


Hi,

 > I don't understand exactly how this would work. You might just need to produce the patch so we can discuss something concrete.

I attached the 3 commits that implements this patch (but are not in a ready to push upstream state :)).  Essentially what it does is add support for the ability to instantiate a template based on a typedef and have this typedef being propagated all the way through.   The code in the rest of clang still would not use this ability.

 > then Bar<Double32_t> and Bar<double> have the same instantiation.
 > You can have lots of different names from many different contexts. How many of these do you track and which name do you want to use?

In our own code, we keep track of what the user requested, for example (s)he may have requested any of:

    Foo<double,double>
    Foo<Double32_t,double>
    Foo<double,Double32_t>
    For<Double32_t,Double32_t>

We keep one representation of the class for each of those instantiation selected by the users.  To generate those instantation, we explicitly construct (or tweak) a TemplateParameterList and call for example Sema::SubstDefaultTemplateArgumentIfAvailable  [This is because we also need the requested type that contains the type to be reflected in the default paramater]

Cheers,
Philippe.

On 7/28/16 1:57 PM, Hal Finkel via cfe-dev wrote:
> ----- Original Message -----
>> From: "Keno Fischer" <kfischer at college.harvard.edu>
>> To: "Hal Finkel" <hfinkel at anl.gov>
>> Cc: "clang developer list" <cfe-dev at lists.llvm.org>, "Reid Kleckner" <rnk at google.com>
>> Sent: Thursday, July 28, 2016 1:48:40 PM
>> Subject: Re: [cfe-dev] Recovering the spelling of a typedef
>>
>>
>> Hi Hal,
>>
>>
>> as Philippe mentioned the patch is used to force through sugar nodes
>> through template instantiation.
>> I think for the ROOT use case, one needs to be careful to only think
>> about this in the context of starting from
>> of fields of a class/struct. I don't think ROOT has any problem with
>> re-doing the template instantiation when
>> it needs to compute the disk layout, but we would need to be sure
>> that all the required information is indeed
>> retained and that there is an API for doing so.
>>
> I don't understand exactly how this would work. You might just need to produce the patch so we can discuss something concrete.
>
>   -Hal
>
>> Keno
>>
>>
>>
>>
>> On Tue, Jul 26, 2016 at 2:40 PM, Hal Finkel < hfinkel at anl.gov >
>> wrote:
>>
>>
>> ----- Original Message -----
>>> From: "Keno Fischer via cfe-dev" < cfe-dev at lists.llvm.org >
>>> To: "Reid Kleckner" < rnk at google.com >
>>> Cc: "clang developer list" < cfe-dev at lists.llvm.org >
>>> Sent: Tuesday, July 26, 2016 1:02:40 PM
>>> Subject: Re: [cfe-dev] Recovering the spelling of a typedef
>>>
>>> Yes, in the very simple cases, no patch is needed, but yes, ROOT
>>> needs
>>> to be able to look through templates which is where the problem
>>> comes
>>> in.
>> What does your patch do?
>>
>> The core problem here is that if you have:
>>
>>>> typedef double Double32_t;
>>>> template <typename T> struct Bar { T f; };
>>>> template struct Bar<Double32_t>;
>> then Bar<Double32_t> and Bar<double> have the same instantiation. You
>> can have lots of different names from many different contexts. How
>> many of these do you track and which name do you want to use?
>>
>> -Hal
>>
>>
>>
>>> On Tue, Jul 26, 2016 at 1:40 PM, Reid Kleckner < rnk at google.com >
>>> wrote:
>>>> In simple cases, this information is already available as type
>>>> sugar nodes.
>>>> Consider this AST dump:
>>>>
>>>> typedef double Double32_t;
>>>> struct Foo { Double32_t f; };
>>>>
>>>> |-TypedefDecl 0xd3af50 <t.cpp:1:1, col:16> col:16 referenced
>>>> |Double32_t
>>>> 'double'
>>>> | `-BuiltinType 0xd09d50 'double'
>>>> `-CXXRecordDecl 0xd3afa0 <line:2:1, col:28> col:8 struct Foo
>>>> definition
>>>> |-CXXRecordDecl 0xd3b0c0 <col:1, col:8> col:8 implicit struct Foo
>>>> `-FieldDecl 0xd3b190 <col:14, col:25> col:25 f
>>>> 'Double32_t':'double'
>>>>
>>>> Template instantiation uses the canonical, desugared types,
>>>> though.
>>>> You can
>>>> see it from this dump:
>>>>
>>>> typedef double Double32_t;
>>>> template <typename T> struct Bar { T f; };
>>>> template struct Bar<Double32_t>;
>>>>
>>>> `-ClassTemplateSpecializationDecl 0xc3b490 <line:3:1, col:31>
>>>> col:17 struct
>>>> Bar definition
>>>> |-TemplateArgument type 'double'
>>>> |-CXXRecordDecl 0xc3b688 prev 0xc3b490 <line:2:23, col:30> col:30
>>>> |implicit
>>>> struct Bar
>>>> `-FieldDecl 0xc3b758 <col:36, col:38> col:38 f 'double':'double'
>>>>
>>>> Does ROOT need a way to push the type sugar nodes through
>>>> template
>>>> instantiation? I seem to recall that there are reasons why it's
>>>> hard to do
>>>> that from an implementation standpoint, but it would also help us
>>>> get better
>>>> diagnostics when rinsing "std::string" through a template type
>>>> parameter,
>>>> for example.
>>>>
>>>> On Tue, Jul 26, 2016 at 9:58 AM, Keno Fischer
>>>> < kfischer at college.harvard.edu >
>>>> wrote:
>>>>> Yes, precisely. I am not fully versed in the details (Axel,
>>>>> Philippe,
>>>>> please correct any inaccuracies), but essentially you can
>>>>> request
>>>>> an object
>>>>> to be written to/ read from disk and ROOT will look up the
>>>>> corresponding
>>>>> class and compute the appropriate disk format (for which it
>>>>> needs
>>>>> to
>>>>> distinguish between double/Double32_t for any members). ROOT use
>>>>> a
>>>>> C++
>>>>> Interpreter/JIT (custom one for a very long time, transitioning
>>>>> to
>>>>> LLVM/Clang) for interactivity and introspection, so it has the
>>>>> ASTs for all
>>>>> classes in the system available.
>>>>>
>>>>> On Tue, Jul 26, 2016 at 12:36 PM, Reid Kleckner < rnk at google.com
>>>>> wrote:
>>>>>> Can you elaborate on how this typedef information is used for
>>>>>> I/O? Do you
>>>>>> mean that it is used by some clang plugin that examines the
>>>>>> AST,
>>>>>> or
>>>>>> something else?
>>>>>>
>>>>>> On Mon, Jul 25, 2016 at 6:55 PM, Keno Fischer via cfe-dev
>>>>>> < cfe-dev at lists.llvm.org > wrote:
>>>>>>> Hi Everyone,
>>>>>>>
>>>>>>> We're trying to integrate the CERN ROOT framework with Julia,
>>>>>>> both
>>>>>>> of which use LLVM/Clang for C++ interoperability. As such,
>>>>>>> we're
>>>>>>> hoping
>>>>>>> to harmonize the versions of clang used in both projects. One
>>>>>>> major
>>>>>>> obstacle to this currently is a patch that the ROOT folks are
>>>>>>> carrying
>>>>>>> to support their I/O system which uses the structure of C++
>>>>>>> classes to
>>>>>>> determine the on-disk format. The patch as is isn't really in
>>>>>>> a
>>>>>>> form
>>>>>>> that could be submitted upstream, but we're hoping to solicit
>>>>>>> some
>>>>>>> advice
>>>>>>> to come up with a solution that would be acceptable to clang,
>>>>>>> and not
>>>>>>> require any local code patches.
>>>>>>>
>>>>>>> With that in mind, let us describe the problem:
>>>>>>>
>>>>>>> As mentioned, ROOT uses the structure of C++ classes to
>>>>>>> determine it's
>>>>>>> IO format. The one wrinkle to that is that sometimes the I/O
>>>>>>> storage
>>>>>>> format and the in-memory format are not exactly the same. In
>>>>>>> particular,
>>>>>>> ROOT has a
>>>>>>>
>>>>>>> typedef double Double32_t;
>>>>>>>
>>>>>>> where if this typedef appears in a struct that is serialized
>>>>>>> to
>>>>>>> disk,
>>>>>>> it indicates that it should be stored with 32bit precision on
>>>>>>> disk, but
>>>>>>> with 64bit precision in memory.
>>>>>>>
>>>>>>> That's *only* for I/O information; for anything regarding
>>>>>>> symbols we
>>>>>>> need these two to share their instantiation data.
>>>>>>>
>>>>>>> I.e. we want to distinguish the types of D<double>::m and
>>>>>>> D<Double32_t>::m (and also D<vector<Double32_t>>::m and
>>>>>>> D<vector<double>>::m) in
>>>>>>>
>>>>>>> template <class T>
>>>>>>> struct D {
>>>>>>> using type = std::remove_reference<D>;
>>>>>>> T m;
>>>>>>> static int s;
>>>>>>> };
>>>>>>>
>>>>>>> But &D<double>::s must the the same as D<Double32_t>::s; more
>>>>>>> importantly:
>>>>>>>
>>>>>>> void f(D<double>);
>>>>>>>
>>>>>>> must be called by f(D<Double32_t>{}). That is (IIRC) in
>>>>>>> contrast
>>>>>>> of what
>>>>>>> the C++ committee discussed for strong typedefs.
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> cfe-dev mailing list
>>>>>>> cfe-dev at lists.llvm.org
>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>>>>>>
>>> _______________________________________________
>>> cfe-dev mailing list
>>> cfe-dev at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>>
>> --
>> Hal Finkel
>> Assistant Computational Scientist
>> Leadership Computing Facility
>> Argonne National Laboratory
>>
>>

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Intentionally-ugly-but-minimally-invasive-hack.patch
Type: text/x-diff
Size: 11463 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160730/bdc50a3a/attachment.patch>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-Add-support-for-default-template-parameters-that-con.patch
Type: text/x-diff
Size: 3725 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160730/bdc50a3a/attachment-0001.patch>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-Extend-SubstTemplateTypeParmType-to-support-non-cano.patch
Type: text/x-diff
Size: 2927 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160730/bdc50a3a/attachment-0002.patch>


More information about the cfe-dev mailing list