Changes in / [70284830:f6cc2096]

1 edited


  • doc/proposals/virtual.txt

    r70284830 rf6cc2096  
    148148This gives us an important extra feature, runtime checking of the parent-child
    149 relationship with a C++ dynamic_cast like operation. Allowing checked
    150 conversions from trait references to more particular references, which works
    151 if the underlying type is, or is a child of, the new trait type.
     149relationship with virtual cast, where a pointer (and maybe a reference) to
     150a virtual type can be cast to another virtual cast. However the cast is
     151dynamicly check and only occurs if the underlying type is a child of the type
     152being cast to. Otherwise null is returned.
     154(virtual TYPE)EXPR
     156As an extention, the TYPE may be ommitted if it can be determained from
     157context, for instance if the cast occurs on the right hand side of an
    153160Extension: Multiple Parents
    251258autogenerated and often unique.
     260It may be worth looking into a way to force the vtable pointer to be in a
     261particular location, which would save the storage to store the offset and
     262maybe the offset operation itself (offset = 0). However it may not be worth
     263introducing a new language feature for.
     264As of writing, exceptions actually use this system.
    254267Keyword Usage:
    276289Calling free on a trait reference will free the memory for the object. It will
    277290leave the vtables alone, as those are (always?) statically allocated.
     293Special Traits:
     295trait is_virtual_parent(dtype parent, dtype child) { ... };
     297There are others but I believe this one to be the most important. The trait
     298holds if the parent type is a strict virtual ancestor (any number of levels)
     299of child. It will have to exist at least internally to check for upcasts and
     300it can also be used to optimize virtual casts into upcasts. Or a null value or
     301error if the cast would never succeed. Exporting it to a special trait allows
     302users to express that requirement in their own polymorphic code.
     307Before we can generate any of the nessasary code, the compiler has to get some
     308additional information about the code that it currently does not collect.
     310First it should establish all child->parent links so that it may travel up the
     311hierarchy to grab the nessasary information, and create the actual parent
     312pointers in the strict virtual tables. It should also maintain the connections
     313between the virtual type (structure or trait), the vtable type and the vtable
     314instance (or default instance for relaxed virtual if multiple are allowed). To
     315this end a sub-node should be created with the nessasary pointers. Traits and
     316structs with virtual can create an instance and store all the nessasary data.
     318With the hierarchy in place it can generate the vtable type for each type,
     319it will generally have a function pointer field for each type assertion in
     320some consistant order. Strict virtual will also have a pointer to the parent's
     321vtable and intrusive vtables will also have the offset to recover the original
     322pointer. Sized types will also carry the size.
     324Wheither the vtable is intrusive or not should also be save so that the trait
     325object/reference/pointer knows if it has to store 1 or 2 pointers. A wrapper
     326function will have to be generated for each type assertion so that they may
     327be called on the trait type, these can probably be inlined.
     329The virtual parameter will also have to be marked (implicately or explicately)
     330until code generation so that the wrapper functions know where to go to get
     331the vtable for the function look up. That could probably be added as a
     332storageclass, although one that is only valid on type assertions.
     334The generated vtable will than have to have a vtable instance created and
     335filled with all the approprate values. Stricter matching may have to be used
     336to ensure that the functions used are stable. It will also have to use
     337".gnu.linkonce" or equilant to ensure only one copy exists in the final code
Note: See TracChangeset for help on using the changeset viewer.