Changeset 84993ff2


Ignore:
Timestamp:
Aug 15, 2017, 11:09:40 AM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
08fc48f
Parents:
c3acf0aa (diff), 6a36975 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
7 added
1 deleted
8 edited
2 moved

Legend:

Unmodified
Added
Removed
  • doc/proposals/virtual.txt

    rc3acf0aa r84993ff2  
    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/ControlStruct/MLEMutator.cc

    rc3acf0aa r84993ff2  
    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/TypeData.cc

    rc3acf0aa r84993ff2  
    1010// Created On       : Sat May 16 15:12:51 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 11 10:50:00 2017
    13 // Update Count     : 567
     12// Last Modified On : Mon Aug 14 10:41:00 2017
     13// Update Count     : 568
    1414//
    1515
     
    628628                break;
    629629          case DeclarationNode::Union:
    630                 at = new UnionDecl( *td->aggregate.name, attributes );
     630                at = new UnionDecl( *td->aggregate.name, attributes, linkage );
    631631                buildForall( td->aggregate.params, at->get_parameters() );
    632632                break;
    633633          case DeclarationNode::Trait:
    634                 at = new TraitDecl( *td->aggregate.name, attributes );
     634                at = new TraitDecl( *td->aggregate.name, attributes, linkage );
    635635                buildList( td->aggregate.params, at->get_parameters() );
    636636                break;
     
    649649          case TypeData::Enum: {
    650650                  if ( type->enumeration.body ) {
    651                           EnumDecl * typedecl = buildEnum( type, attributes );
     651                          EnumDecl * typedecl = buildEnum( type, attributes, linkage );
    652652                          return new EnumInstType( buildQualifiers( type ), typedecl );
    653653                  } else {
     
    754754} // buildSymbolic
    755755
    756 EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes ) {
     756EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
    757757        assert( td->kind == TypeData::Enum );
    758         EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes );
     758        EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, linkage );
    759759        buildList( td->enumeration.constants, ret->get_members() );
    760760        list< Declaration * >::iterator members = ret->get_members().begin();
     
    807807                return buildAggregate( td, attributes, linkage );
    808808        } else if ( td->kind == TypeData::Enum ) {
    809                 return buildEnum( td, attributes );
     809                return buildEnum( td, attributes, linkage );
    810810        } else if ( td->kind == TypeData::Symbolic ) {
    811811                return buildSymbolic( td, name, scs, linkage );
  • src/Parser/TypeData.h

    rc3acf0aa r84993ff2  
    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
     
    107107ReferenceToType * buildAggInst( const TypeData * );
    108108TypeDecl * buildVariable( const TypeData * );
    109 EnumDecl * buildEnum( const TypeData *, std::list< Attribute * > );
     109EnumDecl * buildEnum( const TypeData *, std::list< Attribute * >, LinkageSpec::Spec );
    110110TypeInstType * buildSymbolicInst( const TypeData * );
    111111TupleType * buildTuple( const TypeData * );
  • src/ResolvExpr/Resolver.cc

    rc3acf0aa r84993ff2  
    390390
    391391        void Resolver::visit( CatchStmt *catchStmt ) {
     392                Parent::visit( catchStmt );
     393               
    392394                if ( catchStmt->get_cond() ) {
    393395                        Expression * wrapped = new CastExpr(
  • src/SynTree/Declaration.h

    rc3acf0aa r84993ff2  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 11 10:20:00 2017
    13 // Update Count     : 127
     12// Last Modified On : Mon Aug 14 10:15:00 2017
     13// Update Count     : 128
    1414//
    1515
     
    313313        typedef AggregateDecl Parent;
    314314  public:
    315         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 ) {
    316316                assertf( attributes.empty(), "attribute unsupported for traits" );
    317317        }
  • src/SynTree/Statement.cc

    rc3acf0aa r84993ff2  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Jun 12 10:37:00 2017
    13 // Update Count     : 64
     12// Last Modified On : Mon Aug 14 12:26:00 2017
     13// Update Count     : 65
    1414//
    1515
     
    329329void TryStmt::print( std::ostream &os, int indent ) const {
    330330        os << "Try Statement" << endl;
    331         os << string( indent + 2, ' ' ) << "with block: " << endl;
     331        os << string( indent + 2, ' ' ) << "with block:" << endl;
     332        os << string( indent + 4, ' ' );
    332333        block->print( os, indent + 4 );
    333334
    334335        // handlers
    335         os << string( indent + 2, ' ' ) << "and handlers: " << endl;
    336         for ( std::list<CatchStmt *>::const_iterator i = handlers.begin(); i != handlers.end(); i++)
     336        os << string( indent + 2, ' ' ) << "and handlers:" << endl;
     337        for ( std::list<CatchStmt *>::const_iterator i = handlers.begin(); i != handlers.end(); i++) {
     338                os << string( indent + 4, ' ' );
    337339                (*i )->print( os, indent + 4 );
     340        }
    338341
    339342        // finally block
    340343        if ( finallyBlock != 0 ) {
    341                 os << string( indent + 2, ' ' ) << "Finally block: " << endl;
     344                os << string( indent + 2, ' ' ) << "and finally:" << endl;
    342345                finallyBlock->print( os, indent + 4 );
    343346        } // if
     
    360363        os << "Catch " << ((Terminate == kind) ? "Terminate" : "Resume") << " Statement" << endl;
    361364
    362         os << string( indent, ' ' ) << "... catching" << endl;
     365        os << string( indent + 2, ' ' ) << "... catching: ";
    363366        if ( decl ) {
    364367                decl->printShort( os, indent + 4 );
     
    367370        else
    368371                os << string( indent + 4 , ' ' ) << ">>> Error:  this catch clause must have a declaration <<<" << endl;
     372
     373        if ( cond ) {
     374                os << string( indent + 2, ' ' ) << "with conditional:" << endl;
     375                os << string( indent + 4, ' ' );
     376                cond->print( os, indent + 4 );
     377        }
     378        else
     379                os << string( indent + 2, ' ' ) << "with no conditional" << endl;
     380
     381        os << string( indent + 2, ' ' ) << "with block:" << endl;
     382        os << string( indent + 4, ' ' );
     383        body->print( os, indent + 4 );
    369384}
    370385
     
    383398void FinallyStmt::print( std::ostream &os, int indent ) const {
    384399        os << "Finally Statement" << endl;
    385         os << string( indent + 2, ' ' ) << "with block: " << endl;
     400        os << string( indent + 2, ' ' ) << "with block:" << endl;
     401        os << string( indent + 4, ' ' );
    386402        block->print( os, indent + 4 );
    387403}
  • src/tests/.expect/32/math2.txt

    rc3acf0aa r84993ff2  
    1 fmod:1 1 1 1 1 1
    2 remainder:-1 -1 -1
    3 remquo:7 0.0999999 7 0.1 7 0.0999999999999999999
    4 div:7, 0.2 7, 0.2 7, 0.2
    5 fma:-2 -2 -2
    6 fdim:2 2 2
    7 nan:nan nan nan
    8 exp:2.71828 2.71828182845905 2.71828182845904524 1.46869+2.28736i 1.46869393991589+2.28735528717884i 1.46869393991588516+2.28735528717884239i
    9 exp2:2 2 2
    10 expm1:1.71828 1.71828182845905 1.71828182845904524
    11 pow:1 1 1 0.273957+0.583701i 0.273957253830121+0.583700758758615i 0.273957253830121071+0.583700758758614628i
    12 16 256
    13 912673 256 64 -64 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i
    14 log:0 0 0 0.346574+0.785398i 0.346573590279973+0.785398163397448i 0.346573590279972655+0.78539816339744831i
    15 log2:3 3 3
    16 log10:2 2 2
    17 log1p:0.693147 0.693147180559945 0.693147180559945309
    18 ilogb:0 0 0
    19 logb:3 3 3
    20 sqrt:1 1 1 1.09868+0.45509i 1.09868411346781+0.455089860562227i 1.09868411346780997+0.455089860562227341i
    21 cbrt:3 3 3
    22 hypot:1.41421 1.4142135623731 1.41421356237309505
    231sin:0.841471 0.841470984807897 0.841470984807896507 1.29846+0.634964i 1.29845758141598+0.634963914784736i 1.29845758141597729+0.634963914784736108i
    242cos:0.540302 0.54030230586814 0.540302305868139717 0.83373-0.988898i 0.833730025131149-0.988897705762865i 0.833730025131149049-0.988897705762865096i
     
    275acos:0 0 0 0.904557-1.06128i 0.904556894302381-1.06127506190504i 0.904556894302381364-1.06127506190503565i
    286atan:0.785398 0.785398163397448 0.78539816339744831 1.01722+0.402359i 1.01722196789785+0.402359478108525i 1.01722196789785137+0.402359478108525094i
    29 atan2:0.785398 0.785398163397448 0.78539816339744831 atan:0.785398 0.785398163397448 0.78539816339744831 sinh:1.1752 1.1752011936438 1.17520119364380146 0.634964+1.29846i 0.634963914784736+1.29845758141598i 0.634963914784736108+1.29845758141597729i
     7atan2:0.785398 0.785398163397448 0.78539816339744831 atan:0.785398 0.785398163397448 0.78539816339744831
     8sinh:1.1752 1.1752011936438 1.17520119364380146 0.634964+1.29846i 0.634963914784736+1.29845758141598i 0.634963914784736108+1.29845758141597729i
    309cosh:1.54308 1.54308063481524 1.54308063481524378 0.83373+0.988898i 0.833730025131149+0.988897705762865i 0.833730025131149049+0.988897705762865096i
    3110tanh:0.761594 0.761594155955765 0.761594155955764888 1.08392+0.271753i 1.08392332733869+0.271752585319512i 1.08392332733869454+0.271752585319511717i
     
    3817lgamma:1.79176 1 1.79175946922805 1 1.791759469228055 1
    3918tgamma:6 6 6
    40 floor:1 1 1
    41 ceil:2 2 2
    42 trunc:3 3 3
    43 rint:2 2 2
    44 rint:2 2 2
    45 rint:2 2 2
    46 lrint:2 2 2
    47 llrint:2 2 2
    48 nearbyint:4 4 4
    49 round:2 2 2
    50 round:2 2 2
    51 round:2 2 2
    52 lround:2 2 2
    53 llround:2 2 2
    54 copysign:-1 -1 -1
    55 frexp:0.5 3 0.5 3 0.5 3
    56 ldexp:8 8 8
    57 modf:2 0.3 2 0.3 2 0.3
    58 modf:2, 0.3 2, 0.3 2, 0.3
    59 nextafter:2 2 2
    60 nexttoward:2 2 2
    61 scalbn:16 16 16
    62 scalbln:16 16 16
  • src/tests/.expect/64/math2.txt

    rc3acf0aa r84993ff2  
    1 fmod:1 1 1 1 1 1
    2 remainder:-1 -1 -1
    3 remquo:7 0.0999999 7 0.1 7 0.0999999999999999999
    4 div:7, 0.2 7, 0.2 7, 0.2
    5 fma:-2 -2 -2
    6 fdim:2 2 2
    7 nan:nan nan nan
    8 exp:2.71828 2.71828182845905 2.71828182845904524 1.46869+2.28736i 1.46869393991589+2.28735528717884i 1.46869393991588516+2.28735528717884239i
    9 exp2:2 2 2
    10 expm1:1.71828 1.71828182845905 1.71828182845904524
    11 pow:1 1 1 0.273957+0.583701i 0.273957253830121+0.583700758758615i 0.273957253830121071+0.583700758758614627i
    12 16 256
    13 912673 256 64 -64 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i
    14 log:0 0 0 0.346574+0.785398i 0.346573590279973+0.785398163397448i 0.346573590279972655+0.78539816339744831i
    15 log2:3 3 3
    16 log10:2 2 2
    17 log1p:0.693147 0.693147180559945 0.693147180559945309
    18 ilogb:0 0 0
    19 logb:3 3 3
    20 sqrt:1 1 1 1.09868+0.45509i 1.09868411346781+0.455089860562227i 1.09868411346780997+0.455089860562227341i
    21 cbrt:3 3 3
    22 hypot:1.41421 1.4142135623731 1.41421356237309505
    231sin:0.841471 0.841470984807897 0.841470984807896507 1.29846+0.634964i 1.29845758141598+0.634963914784736i 1.29845758141597729+0.634963914784736108i
    242cos:0.540302 0.54030230586814 0.540302305868139717 0.83373-0.988898i 0.833730025131149-0.988897705762865i 0.833730025131149049-0.988897705762865096i
     
    275acos:0 0 0 0.904557-1.06128i 0.904556894302381-1.06127506190504i 0.904556894302381364-1.06127506190503565i
    286atan:0.785398 0.785398163397448 0.78539816339744831 1.01722+0.402359i 1.01722196789785+0.402359478108525i 1.01722196789785137+0.402359478108525094i
    29 atan2:0.785398 0.785398163397448 0.78539816339744831 atan:0.785398 0.785398163397448 0.78539816339744831 sinh:1.1752 1.1752011936438 1.17520119364380146 0.634964+1.29846i 0.634963914784736+1.29845758141598i 0.634963914784736108+1.29845758141597729i
     7atan2:0.785398 0.785398163397448 0.78539816339744831 atan:0.785398 0.785398163397448 0.78539816339744831
     8sinh:1.1752 1.1752011936438 1.17520119364380146 0.634964+1.29846i 0.634963914784736+1.29845758141598i 0.634963914784736108+1.29845758141597729i
    309cosh:1.54308 1.54308063481524 1.54308063481524378 0.83373+0.988898i 0.833730025131149+0.988897705762865i 0.833730025131149049+0.988897705762865096i
    3110tanh:0.761594 0.761594155955765 0.761594155955764888 1.08392+0.271753i 1.08392332733869+0.271752585319512i 1.08392332733869454+0.271752585319511717i
     
    3817lgamma:1.79176 1 1.79175946922805 1 1.791759469228055 1
    3918tgamma:6 6 6
    40 floor:1 1 1
    41 ceil:2 2 2
    42 trunc:3 3 3
    43 rint:2 2 2
    44 rint:2 2 2
    45 rint:2 2 2
    46 lrint:2 2 2
    47 llrint:2 2 2
    48 nearbyint:4 4 4
    49 round:2 2 2
    50 round:2 2 2
    51 round:2 2 2
    52 lround:2 2 2
    53 llround:2 2 2
    54 copysign:-1 -1 -1
    55 frexp:0.5 3 0.5 3 0.5 3
    56 ldexp:8 8 8
    57 modf:2 0.3 2 0.3 2 0.3
    58 modf:2, 0.3 2, 0.3 2, 0.3
    59 nextafter:2 2 2
    60 nexttoward:2 2 2
    61 scalbn:16 16 16
    62 scalbln:16 16 16
  • src/tests/except-2.c

    rc3acf0aa r84993ff2  
    55
    66// Local Exception Types and manual vtable types.
     7#define GLUE2(left, right) left##right
     8#define GLUE3(left, middle, right) left##middle##right
    79#define BASE_EXCEPT __cfaehm__base_exception_t
    8 #define TABLE(name) name##_vtable
    9 #define INSTANCE(name) _##name##_vtable_instance
     10#define TABLE(name) GLUE2(name,_vtable)
     11#define INSTANCE(name) GLUE3(_,name,_vtable_instance)
    1012#define TRIVIAL_EXCEPTION(name) \
    1113struct name; \
    1214struct TABLE(name) { \
    13         struct __cfaehm__base_exception_t_vtable const * parent; \
     15        struct TABLE(BASE_EXCEPT) const * parent; \
    1416        size_t size; \
    1517        void (*copy)(name *this, name * other); \
     
    2830} \
    2931TABLE(name) INSTANCE(name) @= { \
    30         .parent : &INSTANCE(__cfaehm__base_exception_t), \
     32        .parent : &INSTANCE(BASE_EXCEPT), \
    3133        .size : sizeof(name), .copy : name##_copy, \
    3234        .free : ^?{}, .msg : name##_msg \
     
    4042struct num_error;
    4143struct num_error_vtable {
    42         struct exception_t_vtable const * parent;
     44        struct TABLE(BASE_EXCEPT) const * parent;
    4345        size_t size;
    4446        void (*copy)(num_error *this, num_error * other);
     
    6264}
    6365void ?{}(num_error * this, int num) {
    64         this->virtual_table = &_num_error_vtable_instance;
     66        this->virtual_table = &INSTANCE(num_error);
    6567        this->msg = 0;
    6668        this->num = num;
Note: See TracChangeset for help on using the changeset viewer.