Changes in / [8217e8f:36a5a77]


Ignore:
Files:
3 added
9 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/virtual.txt

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

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

    r8217e8f r36a5a77  
    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 
    175156
    176157        Statement *MLEMutator::mutate( BranchStmt *branchStmt ) throw ( SemanticError ) {
     
    223204                } // switch
    224205
    225                 // add unused attribute to label to silence warnings
    226                 addUnused( targetEntry->get_controlStructure(), branchStmt->get_originalTarget() );
    227 
    228206                // transform break/continue statements into goto to simplify later handling of branches
    229207                delete branchStmt;
  • src/Parser/DeclarationNode.cc

    r8217e8f r36a5a77  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Aug 10 17:02:00 2017
    13 // Update Count     : 1021
     12// Last Modified On : Fri Jul 14 16:55:00 2017
     13// Update Count     : 1020
    1414//
    1515
     
    275275        return newnode;
    276276} // DeclarationNode::newEnumConstant
     277
     278DeclarationNode * 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
    277291
    278292DeclarationNode * DeclarationNode::newName( string * name ) {
  • src/Parser/ParseNode.h

    r8217e8f r36a5a77  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:28:16 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thu Aug 10 16:54:00 2017
    13 // Update Count     : 789
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Jul 27 12:08:08 2017
     13// Update Count     : 788
    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
    250253        DeclarationNode();
    251254        ~DeclarationNode();
     
    332335
    333336        static UniqueName anonymous;
     337
     338        // Temp to test TreeStruct
     339        const std::string * parent_name;
    334340}; // DeclarationNode
    335341
  • src/Parser/TypeData.cc

    r8217e8f r36a5a77  
    1010// Created On       : Sat May 16 15:12:51 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Aug 14 10:41:00 2017
    13 // Update Count     : 568
     12// Last Modified On : Wed Aug  9 13:50:00 2017
     13// Update Count     : 567
    1414//
    1515
     
    6464                aggregate.fields = nullptr;
    6565                aggregate.body = false;
     66                aggregate.tagged = false;
     67                aggregate.parent = nullptr;
    6668                break;
    6769          case AggregateInst:
     
    123125                delete aggregate.actuals;
    124126                delete aggregate.fields;
     127                delete aggregate.parent;
    125128                // delete aggregate;
    126129                break;
     
    637640        switch ( td->aggregate.kind ) {
    638641          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                }
    639647          case DeclarationNode::Coroutine:
    640648          case DeclarationNode::Monitor:
     
    644652                break;
    645653          case DeclarationNode::Union:
    646                 at = new UnionDecl( *td->aggregate.name, attributes, linkage );
     654                at = new UnionDecl( *td->aggregate.name, attributes );
    647655                buildForall( td->aggregate.params, at->get_parameters() );
    648656                break;
    649657          case DeclarationNode::Trait:
    650                 at = new TraitDecl( *td->aggregate.name, attributes, linkage );
     658                at = new TraitDecl( *td->aggregate.name, attributes );
    651659                buildList( td->aggregate.params, at->get_parameters() );
    652660                break;
     
    665673          case TypeData::Enum: {
    666674                  if ( type->enumeration.body ) {
    667                           EnumDecl * typedecl = buildEnum( type, attributes, linkage );
     675                          EnumDecl * typedecl = buildEnum( type, attributes );
    668676                          return new EnumInstType( buildQualifiers( type ), typedecl );
    669677                  } else {
     
    770778} // buildSymbolic
    771779
    772 EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
     780EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes ) {
    773781        assert( td->kind == TypeData::Enum );
    774         EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, linkage );
     782        EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes );
    775783        buildList( td->enumeration.constants, ret->get_members() );
    776784        list< Declaration * >::iterator members = ret->get_members().begin();
     
    823831                return buildAggregate( td, attributes, linkage );
    824832        } else if ( td->kind == TypeData::Enum ) {
    825                 return buildEnum( td, attributes, linkage );
     833                return buildEnum( td, attributes );
    826834        } else if ( td->kind == TypeData::Symbolic ) {
    827835                return buildSymbolic( td, name, scs, linkage );
  • src/Parser/TypeData.h

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

    r8217e8f r36a5a77  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Aug 14 10:15:00 2017
    13 // Update Count     : 128
     12// Last Modified On : Wed Aug  9 14:45:00 2017
     13// Update Count     : 126
    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 ) {}
    272         StructDecl( const StructDecl &other ) : Parent( other ), kind( other.kind ) {}
     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 ) {}
    273274
    274275        bool is_coroutine() { return kind == DeclarationNode::Coroutine; }
     
    276277        bool is_thread() { return kind == DeclarationNode::Thread; }
    277278
     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
    278285        virtual StructDecl *clone() const { return new StructDecl( *this ); }
    279286        virtual void accept( Visitor &v ) { v.visit( this ); }
     
    282289        DeclarationNode::Aggregate kind;
    283290        virtual std::string typeString() const;
     291
     292        bool tagged;
     293        std::string parent_name;
    284294};
    285295
     
    313323        typedef AggregateDecl Parent;
    314324  public:
    315         TraitDecl( const std::string &name, const std::list< Attribute * > & attributes, LinkageSpec::Spec linkage ) : Parent( name, attributes, linkage ) {
     325        TraitDecl( const std::string &name, const std::list< Attribute * > & attributes ) : Parent( name ) {
    316326                assertf( attributes.empty(), "attribute unsupported for traits" );
    317327        }
  • src/tests/pybin/tools.py

    r8217e8f r36a5a77  
    8585                                "--unchanged-group-format='%%=' \\"
    8686                                "--changed-group-format='\t\texpected :\n"
    87                                 "%%<"
     87                                "%%<\n"
    8888                                "\t\tgot :\n"
    89                                 "%%>\n' \\\n"
     89                                "%%>' \\\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.