Changes in / [36a5a77:8217e8f]


Ignore:
Files:
9 added
3 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/virtual.txt

    r36a5a77 r8217e8f  
    147147
    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.
     153
     154(virtual TYPE)EXPR
     155
     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
     158assignment.
    152159
    153160Extension: Multiple Parents
     
    251258autogenerated and often unique.
    252259
     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.
     265
    253266
    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.
     291
     292
     293Special Traits:
     294
     295trait is_virtual_parent(dtype parent, dtype child) { ... };
     296
     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.
     303
     304
     305Implementation:
     306
     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.
     309
     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.
     317
     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.
     323
     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.
     328
     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.
     333
     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
     338base.
  • src/Common/Indenter.h

    r36a5a77 r8217e8f  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // utility.h --
     7// Indenter.h --
    88//
    9 // Author           : Richard C. Bilson
    10 // Created On       : Mon May 18 07:44:20 2015
     9// Author           : Rob Schluntz
     10// Created On       : Fri Jun 30 16:55:23 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri May 5 11:03:00 2017
    13 // Update Count     : 32
     12// Last Modified On : Fri Aug 11 11:15:00 2017
     13// Update Count     : 1
    1414//
    1515
  • src/ControlStruct/MLEMutator.cc

    r36a5a77 r8217e8f  
    154154                return switchStmt;
    155155        }
     156
     157        void addUnused( Statement * stmt, const Label & originalTarget ) {
     158                // break/continue without a label doesn't need unused attribute
     159                if ( originalTarget == "" ) return;
     160                // add unused attribute to the originalTarget of a labelled break/continue
     161                for ( Label & l : stmt->get_labels() ) {
     162                        // find the label to add unused attribute to
     163                        if ( l == originalTarget ) {
     164                                for ( Attribute * attr : l.get_attributes() ) {
     165                                        // ensure attribute isn't added twice
     166                                        if ( attr->get_name() == "unused" ) return;
     167                                }
     168                                l.get_attributes().push_back( new Attribute( "unused" ) );
     169                                return;
     170                        }
     171                }
     172                assertf( false, "Could not find label '%s' on statement %s", originalTarget.get_name().c_str(), toString( stmt ).c_str() );
     173        }
     174
    156175
    157176        Statement *MLEMutator::mutate( BranchStmt *branchStmt ) throw ( SemanticError ) {
     
    204223                } // switch
    205224
     225                // add unused attribute to label to silence warnings
     226                addUnused( targetEntry->get_controlStructure(), branchStmt->get_originalTarget() );
     227
    206228                // transform break/continue statements into goto to simplify later handling of branches
    207229                delete branchStmt;
  • src/Parser/DeclarationNode.cc

    r36a5a77 r8217e8f  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jul 14 16:55:00 2017
    13 // Update Count     : 1020
     12// Last Modified On : Thr Aug 10 17:02:00 2017
     13// Update Count     : 1021
    1414//
    1515
     
    275275        return newnode;
    276276} // DeclarationNode::newEnumConstant
    277 
    278 DeclarationNode * DeclarationNode::newTreeStruct( Aggregate kind, const string * name, const string * parent, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
    279         assert( name );
    280         DeclarationNode * newnode = new DeclarationNode;
    281         newnode->type = new TypeData( TypeData::Aggregate );
    282         newnode->type->aggregate.kind = kind;
    283         newnode->type->aggregate.name = name;
    284         newnode->type->aggregate.actuals = actuals;
    285         newnode->type->aggregate.fields = fields;
    286         newnode->type->aggregate.body = body;
    287         newnode->type->aggregate.tagged = true;
    288         newnode->type->aggregate.parent = parent;
    289         return newnode;
    290 } // DeclarationNode::newTreeStruct
    291277
    292278DeclarationNode * DeclarationNode::newName( string * name ) {
  • src/Parser/ParseNode.h

    r36a5a77 r8217e8f  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:28:16 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 27 12:08:08 2017
    13 // Update Count     : 788
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Aug 10 16:54:00 2017
     13// Update Count     : 789
    1414//
    1515
     
    248248        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
    249249
    250         // Perhaps this would best fold into newAggragate.
    251         static DeclarationNode * newTreeStruct( Aggregate kind, const std::string * name, const std::string * parent, ExpressionNode * actuals, DeclarationNode * fields, bool body );
    252 
    253250        DeclarationNode();
    254251        ~DeclarationNode();
     
    335332
    336333        static UniqueName anonymous;
    337 
    338         // Temp to test TreeStruct
    339         const std::string * parent_name;
    340334}; // DeclarationNode
    341335
  • src/Parser/TypeData.cc

    r36a5a77 r8217e8f  
    1010// Created On       : Sat May 16 15:12:51 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Aug  9 13:50:00 2017
    13 // Update Count     : 567
     12// Last Modified On : Mon Aug 14 10:41:00 2017
     13// Update Count     : 568
    1414//
    1515
     
    6464                aggregate.fields = nullptr;
    6565                aggregate.body = false;
    66                 aggregate.tagged = false;
    67                 aggregate.parent = nullptr;
    6866                break;
    6967          case AggregateInst:
     
    125123                delete aggregate.actuals;
    126124                delete aggregate.fields;
    127                 delete aggregate.parent;
    128125                // delete aggregate;
    129126                break;
     
    640637        switch ( td->aggregate.kind ) {
    641638          case DeclarationNode::Struct:
    642                 if ( td->aggregate.tagged ) {
    643                         at = new StructDecl( *td->aggregate.name, td->aggregate.parent, attributes, linkage );
    644                         buildForall( td->aggregate.params, at->get_parameters() );
    645                         break;
    646                 }
    647639          case DeclarationNode::Coroutine:
    648640          case DeclarationNode::Monitor:
     
    652644                break;
    653645          case DeclarationNode::Union:
    654                 at = new UnionDecl( *td->aggregate.name, attributes );
     646                at = new UnionDecl( *td->aggregate.name, attributes, linkage );
    655647                buildForall( td->aggregate.params, at->get_parameters() );
    656648                break;
    657649          case DeclarationNode::Trait:
    658                 at = new TraitDecl( *td->aggregate.name, attributes );
     650                at = new TraitDecl( *td->aggregate.name, attributes, linkage );
    659651                buildList( td->aggregate.params, at->get_parameters() );
    660652                break;
     
    673665          case TypeData::Enum: {
    674666                  if ( type->enumeration.body ) {
    675                           EnumDecl * typedecl = buildEnum( type, attributes );
     667                          EnumDecl * typedecl = buildEnum( type, attributes, linkage );
    676668                          return new EnumInstType( buildQualifiers( type ), typedecl );
    677669                  } else {
     
    778770} // buildSymbolic
    779771
    780 EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes ) {
     772EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
    781773        assert( td->kind == TypeData::Enum );
    782         EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes );
     774        EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, linkage );
    783775        buildList( td->enumeration.constants, ret->get_members() );
    784776        list< Declaration * >::iterator members = ret->get_members().begin();
     
    831823                return buildAggregate( td, attributes, linkage );
    832824        } else if ( td->kind == TypeData::Enum ) {
    833                 return buildEnum( td, attributes );
     825                return buildEnum( td, attributes, linkage );
    834826        } else if ( td->kind == TypeData::Symbolic ) {
    835827                return buildSymbolic( td, name, scs, linkage );
  • src/Parser/TypeData.h

    r36a5a77 r8217e8f  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 15:18:36 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:32:47 2017
    13 // Update Count     : 188
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Aug 14 10:38:00 2017
     13// Update Count     : 189
    1414//
    1515
     
    108108ReferenceToType * buildAggInst( const TypeData * );
    109109TypeDecl * buildVariable( const TypeData * );
    110 EnumDecl * buildEnum( const TypeData *, std::list< Attribute * > );
     110EnumDecl * buildEnum( const TypeData *, std::list< Attribute * >, LinkageSpec::Spec );
    111111TypeInstType * buildSymbolicInst( const TypeData * );
    112112TupleType * buildTuple( const TypeData * );
  • src/SynTree/Declaration.h

    r36a5a77 r8217e8f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Aug  9 14:45:00 2017
    13 // Update Count     : 126
     12// Last Modified On : Mon Aug 14 10:15:00 2017
     13// Update Count     : 128
    1414//
    1515
     
    269269        typedef AggregateDecl Parent;
    270270  public:
    271         StructDecl( const std::string &name, DeclarationNode::Aggregate kind = DeclarationNode::Struct, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall ) : Parent( name, attributes, linkage ), kind( kind ), tagged( false ), parent_name( "" ) {}
    272         StructDecl( const std::string &name, const std::string *parent, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall ) : Parent( name, attributes, linkage ), kind( DeclarationNode::Struct ), tagged( true ), parent_name( parent ? *parent : "" ) {}
    273         StructDecl( const StructDecl &other ) : Parent( other ) {}
     271        StructDecl( const std::string &name, DeclarationNode::Aggregate kind = DeclarationNode::Struct, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall ) : Parent( name, attributes, linkage ), kind( kind ) {}
     272        StructDecl( const StructDecl &other ) : Parent( other ), kind( other.kind ) {}
    274273
    275274        bool is_coroutine() { return kind == DeclarationNode::Coroutine; }
     
    277276        bool is_thread() { return kind == DeclarationNode::Thread; }
    278277
    279         // Tagged/Tree Structure Excetion
    280         bool get_tagged() { return tagged; }
    281         void set_tagged( bool newValue ) { tagged = newValue; }
    282         bool has_parent() { return parent_name != ""; }
    283         std::string get_parentName() { return parent_name; }
    284 
    285278        virtual StructDecl *clone() const { return new StructDecl( *this ); }
    286279        virtual void accept( Visitor &v ) { v.visit( this ); }
     
    289282        DeclarationNode::Aggregate kind;
    290283        virtual std::string typeString() const;
    291 
    292         bool tagged;
    293         std::string parent_name;
    294284};
    295285
     
    323313        typedef AggregateDecl Parent;
    324314  public:
    325         TraitDecl( const std::string &name, const std::list< Attribute * > & attributes ) : Parent( name ) {
     315        TraitDecl( const std::string &name, const std::list< Attribute * > & attributes, LinkageSpec::Spec linkage ) : Parent( name, attributes, linkage ) {
    326316                assertf( attributes.empty(), "attribute unsupported for traits" );
    327317        }
  • src/tests/pybin/tools.py

    r36a5a77 r8217e8f  
    8585                                "--unchanged-group-format='%%=' \\"
    8686                                "--changed-group-format='\t\texpected :\n"
    87                                 "%%<\n"
     87                                "%%<"
    8888                                "\t\tgot :\n"
    89                                 "%%>' \\\n"
     89                                "%%>\n' \\\n"
    9090                                "--new-line-format='\t\t%%dn\t%%L' \\\n"
    9191                                "--old-line-format='\t\t%%dn\t%%L' \\\n"
     
    9494
    9595        # fetch return code and error from the diff command
    96         return sh(diff_cmd % (lhs, rhs), dry_run, False)       
     96        return sh(diff_cmd % (lhs, rhs), dry_run, False)
Note: See TracChangeset for help on using the changeset viewer.