Changes in / [8217e8f:36a5a77]
- Files:
-
- 3 added
- 9 deleted
- 9 edited
-
doc/proposals/virtual.txt (modified) (3 diffs)
-
src/Common/Indenter.h (modified) (1 diff)
-
src/ControlStruct/MLEMutator.cc (modified) (2 diffs)
-
src/Parser/DeclarationNode.cc (modified) (2 diffs)
-
src/Parser/ParseNode.h (modified) (3 diffs)
-
src/Parser/TypeData.cc (modified) (8 diffs)
-
src/Parser/TypeData.h (modified) (2 diffs)
-
src/SynTree/Declaration.h (modified) (5 diffs)
-
src/tests/.expect/32/math.txt (added)
-
src/tests/.expect/32/math1.txt (deleted)
-
src/tests/.expect/32/math2.txt (deleted)
-
src/tests/.expect/32/math3.txt (deleted)
-
src/tests/.expect/64/math.txt (added)
-
src/tests/.expect/64/math1.txt (deleted)
-
src/tests/.expect/64/math2.txt (deleted)
-
src/tests/.expect/64/math3.txt (deleted)
-
src/tests/math.c (added)
-
src/tests/math1.c (deleted)
-
src/tests/math2.c (deleted)
-
src/tests/math3.c (deleted)
-
src/tests/pybin/tools.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/virtual.txt
r8217e8f r36a5a77 147 147 148 148 This 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. 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. 159 152 160 153 Extension: Multiple Parents … … 258 251 autogenerated and often unique. 259 252 260 It may be worth looking into a way to force the vtable pointer to be in a261 particular location, which would save the storage to store the offset and262 maybe the offset operation itself (offset = 0). However it may not be worth263 introducing a new language feature for.264 As of writing, exceptions actually use this system.265 266 253 267 254 Keyword Usage: … … 289 276 Calling free on a trait reference will free the memory for the object. It will 290 277 leave 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 trait298 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 and300 it can also be used to optimize virtual casts into upcasts. Or a null value or301 error if the cast would never succeed. Exporting it to a special trait allows302 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 some308 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 the311 hierarchy to grab the nessasary information, and create the actual parent312 pointers in the strict virtual tables. It should also maintain the connections313 between the virtual type (structure or trait), the vtable type and the vtable314 instance (or default instance for relaxed virtual if multiple are allowed). To315 this end a sub-node should be created with the nessasary pointers. Traits and316 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 in320 some consistant order. Strict virtual will also have a pointer to the parent's321 vtable and intrusive vtables will also have the offset to recover the original322 pointer. Sized types will also carry the size.323 324 Wheither the vtable is intrusive or not should also be save so that the trait325 object/reference/pointer knows if it has to store 1 or 2 pointers. A wrapper326 function will have to be generated for each type assertion so that they may327 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 get331 the vtable for the function look up. That could probably be added as a332 storageclass, although one that is only valid on type assertions.333 334 The generated vtable will than have to have a vtable instance created and335 filled with all the approprate values. Stricter matching may have to be used336 to ensure that the functions used are stable. It will also have to use337 ".gnu.linkonce" or equilant to ensure only one copy exists in the final code338 base. -
src/Common/Indenter.h
r8217e8f r36a5a77 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Indenter.h --7 // utility.h -- 8 8 // 9 // Author : R ob Schluntz10 // Created On : Fri Jun 30 16:55:23 20179 // Author : Richard C. Bilson 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 11 11:15:00 201713 // Update Count : 112 // Last Modified On : Fri May 5 11:03:00 2017 13 // Update Count : 32 14 14 // 15 15 -
src/ControlStruct/MLEMutator.cc
r8217e8f r36a5a77 154 154 return switchStmt; 155 155 } 156 157 void addUnused( Statement * stmt, const Label & originalTarget ) {158 // break/continue without a label doesn't need unused attribute159 if ( originalTarget == "" ) return;160 // add unused attribute to the originalTarget of a labelled break/continue161 for ( Label & l : stmt->get_labels() ) {162 // find the label to add unused attribute to163 if ( l == originalTarget ) {164 for ( Attribute * attr : l.get_attributes() ) {165 // ensure attribute isn't added twice166 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 175 156 176 157 Statement *MLEMutator::mutate( BranchStmt *branchStmt ) throw ( SemanticError ) { … … 223 204 } // switch 224 205 225 // add unused attribute to label to silence warnings226 addUnused( targetEntry->get_controlStructure(), branchStmt->get_originalTarget() );227 228 206 // transform break/continue statements into goto to simplify later handling of branches 229 207 delete branchStmt; -
src/Parser/DeclarationNode.cc
r8217e8f r36a5a77 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Aug 10 17:02:00 201713 // Update Count : 102 112 // Last Modified On : Fri Jul 14 16:55:00 2017 13 // Update Count : 1020 14 14 // 15 15 … … 275 275 return newnode; 276 276 } // 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 277 291 278 292 DeclarationNode * DeclarationNode::newName( string * name ) { -
src/Parser/ParseNode.h
r8217e8f r36a5a77 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:28:16 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Thu Aug 10 16:54:00201713 // Update Count : 78 911 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 27 12:08:08 2017 13 // Update Count : 788 14 14 // 15 15 … … 248 248 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement 249 249 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 250 253 DeclarationNode(); 251 254 ~DeclarationNode(); … … 332 335 333 336 static UniqueName anonymous; 337 338 // Temp to test TreeStruct 339 const std::string * parent_name; 334 340 }; // DeclarationNode 335 341 -
src/Parser/TypeData.cc
r8217e8f r36a5a77 10 10 // Created On : Sat May 16 15:12:51 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Aug 14 10:41:00 201713 // Update Count : 56 812 // Last Modified On : Wed Aug 9 13:50:00 2017 13 // Update Count : 567 14 14 // 15 15 … … 64 64 aggregate.fields = nullptr; 65 65 aggregate.body = false; 66 aggregate.tagged = false; 67 aggregate.parent = nullptr; 66 68 break; 67 69 case AggregateInst: … … 123 125 delete aggregate.actuals; 124 126 delete aggregate.fields; 127 delete aggregate.parent; 125 128 // delete aggregate; 126 129 break; … … 637 640 switch ( td->aggregate.kind ) { 638 641 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 } 639 647 case DeclarationNode::Coroutine: 640 648 case DeclarationNode::Monitor: … … 644 652 break; 645 653 case DeclarationNode::Union: 646 at = new UnionDecl( *td->aggregate.name, attributes , linkage);654 at = new UnionDecl( *td->aggregate.name, attributes ); 647 655 buildForall( td->aggregate.params, at->get_parameters() ); 648 656 break; 649 657 case DeclarationNode::Trait: 650 at = new TraitDecl( *td->aggregate.name, attributes , linkage);658 at = new TraitDecl( *td->aggregate.name, attributes ); 651 659 buildList( td->aggregate.params, at->get_parameters() ); 652 660 break; … … 665 673 case TypeData::Enum: { 666 674 if ( type->enumeration.body ) { 667 EnumDecl * typedecl = buildEnum( type, attributes , linkage);675 EnumDecl * typedecl = buildEnum( type, attributes ); 668 676 return new EnumInstType( buildQualifiers( type ), typedecl ); 669 677 } else { … … 770 778 } // buildSymbolic 771 779 772 EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes , LinkageSpec::Spec linkage) {780 EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes ) { 773 781 assert( td->kind == TypeData::Enum ); 774 EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes , linkage);782 EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes ); 775 783 buildList( td->enumeration.constants, ret->get_members() ); 776 784 list< Declaration * >::iterator members = ret->get_members().begin(); … … 823 831 return buildAggregate( td, attributes, linkage ); 824 832 } else if ( td->kind == TypeData::Enum ) { 825 return buildEnum( td, attributes , linkage);833 return buildEnum( td, attributes ); 826 834 } else if ( td->kind == TypeData::Symbolic ) { 827 835 return buildSymbolic( td, name, scs, linkage ); -
src/Parser/TypeData.h
r8217e8f r36a5a77 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 15:18:36 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Mon Aug 14 10:38:00201713 // Update Count : 18 911 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:32:47 2017 13 // Update Count : 188 14 14 // 15 15 … … 108 108 ReferenceToType * buildAggInst( const TypeData * ); 109 109 TypeDecl * buildVariable( const TypeData * ); 110 EnumDecl * buildEnum( const TypeData *, std::list< Attribute * > , LinkageSpec::Spec);110 EnumDecl * buildEnum( const TypeData *, std::list< Attribute * > ); 111 111 TypeInstType * buildSymbolicInst( const TypeData * ); 112 112 TupleType * buildTuple( const TypeData * ); -
src/SynTree/Declaration.h
r8217e8f r36a5a77 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Aug 14 10:15:00 201713 // Update Count : 12 812 // Last Modified On : Wed Aug 9 14:45:00 2017 13 // Update Count : 126 14 14 // 15 15 … … 269 269 typedef AggregateDecl Parent; 270 270 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 ) {} 273 274 274 275 bool is_coroutine() { return kind == DeclarationNode::Coroutine; } … … 276 277 bool is_thread() { return kind == DeclarationNode::Thread; } 277 278 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 278 285 virtual StructDecl *clone() const { return new StructDecl( *this ); } 279 286 virtual void accept( Visitor &v ) { v.visit( this ); } … … 282 289 DeclarationNode::Aggregate kind; 283 290 virtual std::string typeString() const; 291 292 bool tagged; 293 std::string parent_name; 284 294 }; 285 295 … … 313 323 typedef AggregateDecl Parent; 314 324 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 ) { 316 326 assertf( attributes.empty(), "attribute unsupported for traits" ); 317 327 } -
src/tests/pybin/tools.py
r8217e8f r36a5a77 85 85 "--unchanged-group-format='%%=' \\" 86 86 "--changed-group-format='\t\texpected :\n" 87 "%%< "87 "%%<\n" 88 88 "\t\tgot :\n" 89 "%%> \n' \\\n"89 "%%>' \\\n" 90 90 "--new-line-format='\t\t%%dn\t%%L' \\\n" 91 91 "--old-line-format='\t\t%%dn\t%%L' \\\n" … … 94 94 95 95 # 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.