- Timestamp:
- May 9, 2019, 4:47:53 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- b038fe4
- Parents:
- ec28948 (diff), db27767 (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. - Location:
- src
- Files:
-
- 21 added
- 27 edited
Legend:
- Unmodified
- Added
- Removed
-
src/BasicTypes-gen.cc
rec28948 r02af79b0 1 #include <algorithm> 1 2 #include <queue> 2 3 #include <iostream> … … 340 341 } // for 341 342 code << "\t}; // costMatrix" << endl; 343 344 // maximum conversion cost from int 345 code << "\tstatic const int maxIntCost = " << *max_element(costMatrix[SignedInt], costMatrix[SignedInt] + NUMBER_OF_BASIC_TYPES) << ";" << endl; 342 346 code << "\t"; // indentation for end marker 343 347 344 348 if ( (start = str.find( ENDMK, start + 1 )) == string::npos ) Abort( "end", ConversionCost ); 345 349 if ( (end = str.find( STARTMK, start + 1 )) == string::npos ) Abort( "start", ConversionCost ); -
src/CodeGen/CodeGenerator.cc
rec28948 r02af79b0 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat May 5 09:08:32 201813 // Update Count : 49 411 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr May 2 10:47:00 2019 13 // Update Count : 497 14 14 // 15 15 #include "CodeGenerator.h" … … 83 83 void CodeGenerator::updateLocation( CodeLocation const & to ) { 84 84 // skip if linemarks shouldn't appear or if codelocation is unset 85 if ( ! lineMarks || to.isUnset() ) return;85 if ( !options.lineMarks || to.isUnset() ) return; 86 86 87 87 if ( currentLocation.followedBy( to, 0 ) ) { … … 116 116 } 117 117 118 CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks, bool printExprTypes ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ), printExprTypes( printExprTypes ), endl( *this ) {} 118 CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks, bool printExprTypes ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), options( pretty, genC, lineMarks, printExprTypes ), endl( *this ) {} 119 CodeGenerator::CodeGenerator( std::ostream & os, const Options &options ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), options(options), endl( *this ) {} 119 120 120 121 string CodeGenerator::mangleName( DeclarationWithType * decl ) { 121 122 // GCC builtins should always be printed unmangled 122 if ( pretty || decl->linkage.is_gcc_builtin ) return decl->name;123 if ( options.pretty || decl->linkage.is_gcc_builtin ) return decl->name; 123 124 if ( decl->mangleName != "" ) { 124 125 // need to incorporate scope level in order to differentiate names for destructors … … 164 165 previsit( (BaseSyntaxNode *)node ); 165 166 GuardAction( [this, node](){ 166 if ( printExprTypes && node->result ) {167 output << " /* " << genType( node->result, "", pretty, genC) << " */ ";167 if ( options.printExprTypes && node->result ) { 168 output << " /* " << genType( node->result, "", options ) << " */ "; 168 169 } 169 170 } ); … … 173 174 void CodeGenerator::postvisit( FunctionDecl * functionDecl ) { 174 175 // deleted decls should never be used, so don't print them 175 if ( functionDecl->isDeleted && genC ) return;176 if ( functionDecl->isDeleted && options.genC ) return; 176 177 extension( functionDecl ); 177 178 genAttributes( functionDecl->get_attributes() ); … … 180 181 functionDecl->get_funcSpec().print( output ); 181 182 182 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty, genC ); 183 Options subOptions = options; 184 subOptions.anonymousUnused = functionDecl->has_body(); 185 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), subOptions ); 183 186 184 187 asmName( functionDecl ); … … 194 197 void CodeGenerator::postvisit( ObjectDecl * objectDecl ) { 195 198 // deleted decls should never be used, so don't print them 196 if ( objectDecl->isDeleted && genC ) return;197 if (objectDecl->get_name().empty() && genC ) {199 if ( objectDecl->isDeleted && options.genC ) return; 200 if (objectDecl->get_name().empty() && options.genC ) { 198 201 // only generate an anonymous name when generating C code, otherwise it clutters the output too much 199 202 static UniqueName name = { "__anonymous_object" }; 200 203 objectDecl->set_name( name.newName() ); 204 // Stops unused parameter warnings. 205 if ( options.anonymousUnused ) { 206 objectDecl->attributes.push_back( new Attribute( "unused" ) ); 207 } 201 208 } 202 209 … … 205 212 206 213 handleStorageClass( objectDecl ); 207 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty,genC );214 output << genType( objectDecl->get_type(), mangleName( objectDecl ), options.pretty, options.genC ); 208 215 209 216 asmName( objectDecl ); … … 224 231 225 232 void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) { 226 if( ! aggDecl->parameters.empty() && ! genC ) {233 if( ! aggDecl->parameters.empty() && ! options.genC ) { 227 234 // assertf( ! genC, "Aggregate type parameters should not reach code generation." ); 228 235 output << "forall("; … … 294 301 295 302 void CodeGenerator::postvisit( TraitDecl * traitDecl ) { 296 assertf( ! genC, "TraitDecls should not reach code generation." );303 assertf( ! options.genC, "TraitDecls should not reach code generation." ); 297 304 extension( traitDecl ); 298 305 handleAggregate( traitDecl, "trait " ); … … 300 307 301 308 void CodeGenerator::postvisit( TypedefDecl * typeDecl ) { 302 assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );309 assertf( ! options.genC, "Typedefs are removed and substituted in earlier passes." ); 303 310 output << "typedef "; 304 output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC) << endl;311 output << genType( typeDecl->get_base(), typeDecl->get_name(), options ) << endl; 305 312 } 306 313 307 314 void CodeGenerator::postvisit( TypeDecl * typeDecl ) { 308 assertf( ! genC, "TypeDecls should not reach code generation." );315 assertf( ! options.genC, "TypeDecls should not reach code generation." ); 309 316 output << typeDecl->genTypeString() << " " << typeDecl->name; 310 317 if ( typeDecl->sized ) { … … 371 378 372 379 void CodeGenerator::postvisit( ConstructorInit * init ){ 373 assertf( ! genC, "ConstructorInit nodes should not reach code generation." );380 assertf( ! options.genC, "ConstructorInit nodes should not reach code generation." ); 374 381 // pseudo-output for constructor/destructor pairs 375 382 output << "<ctorinit>{" << endl << ++indent << "ctor: "; … … 507 514 } else { 508 515 // no constructors with 0 or more than 2 parameters 509 assertf( ! genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );516 assertf( ! options.genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." ); 510 517 output << "("; 511 518 (*arg++)->accept( *visitor ); … … 604 611 // an lvalue cast, this has been taken out. 605 612 output << "("; 606 output << genType( castExpr->get_result(), "", pretty, genC);613 output << genType( castExpr->get_result(), "", options ); 607 614 output << ")"; 608 615 } // if … … 612 619 613 620 void CodeGenerator::postvisit( KeywordCastExpr * castExpr ) { 614 assertf( ! genC, "KeywordCast should not reach code generation." );621 assertf( ! options.genC, "KeywordCast should not reach code generation." ); 615 622 extension( castExpr ); 616 623 output << "((" << castExpr->targetString() << " &)"; … … 620 627 621 628 void CodeGenerator::postvisit( VirtualCastExpr * castExpr ) { 622 assertf( ! genC, "VirtualCastExpr should not reach code generation." );629 assertf( ! options.genC, "VirtualCastExpr should not reach code generation." ); 623 630 extension( castExpr ); 624 631 output << "(virtual "; … … 628 635 629 636 void CodeGenerator::postvisit( UntypedMemberExpr * memberExpr ) { 630 assertf( ! genC, "UntypedMemberExpr should not reach code generation." );637 assertf( ! options.genC, "UntypedMemberExpr should not reach code generation." ); 631 638 extension( memberExpr ); 632 639 memberExpr->get_aggregate()->accept( *visitor ); … … 661 668 output << "sizeof("; 662 669 if ( sizeofExpr->get_isType() ) { 663 output << genType( sizeofExpr->get_type(), "", pretty, genC);670 output << genType( sizeofExpr->get_type(), "", options ); 664 671 } else { 665 672 sizeofExpr->get_expr()->accept( *visitor ); … … 673 680 output << "__alignof__("; 674 681 if ( alignofExpr->get_isType() ) { 675 output << genType( alignofExpr->get_type(), "", pretty, genC);682 output << genType( alignofExpr->get_type(), "", options ); 676 683 } else { 677 684 alignofExpr->get_expr()->accept( *visitor ); … … 681 688 682 689 void CodeGenerator::postvisit( UntypedOffsetofExpr * offsetofExpr ) { 683 assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." );690 assertf( ! options.genC, "UntypedOffsetofExpr should not reach code generation." ); 684 691 output << "offsetof("; 685 output << genType( offsetofExpr->get_type(), "", pretty, genC);692 output << genType( offsetofExpr->get_type(), "", options ); 686 693 output << ", " << offsetofExpr->get_member(); 687 694 output << ")"; … … 691 698 // use GCC builtin 692 699 output << "__builtin_offsetof("; 693 output << genType( offsetofExpr->get_type(), "", pretty, genC);700 output << genType( offsetofExpr->get_type(), "", options ); 694 701 output << ", " << mangleName( offsetofExpr->get_member() ); 695 702 output << ")"; … … 697 704 698 705 void CodeGenerator::postvisit( OffsetPackExpr * offsetPackExpr ) { 699 assertf( ! genC, "OffsetPackExpr should not reach code generation." );700 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC) << ")";706 assertf( ! options.genC, "OffsetPackExpr should not reach code generation." ); 707 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", options ) << ")"; 701 708 } 702 709 … … 728 735 extension( commaExpr ); 729 736 output << "("; 730 if ( genC ) {737 if ( options.genC ) { 731 738 // arg1 of a CommaExpr is never used, so it can be safely cast to void to reduce gcc warnings. 732 739 commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) ); … … 739 746 740 747 void CodeGenerator::postvisit( TupleAssignExpr * tupleExpr ) { 741 assertf( ! genC, "TupleAssignExpr should not reach code generation." );748 assertf( ! options.genC, "TupleAssignExpr should not reach code generation." ); 742 749 tupleExpr->stmtExpr->accept( *visitor ); 743 750 } 744 751 745 752 void CodeGenerator::postvisit( UntypedTupleExpr * tupleExpr ) { 746 assertf( ! genC, "UntypedTupleExpr should not reach code generation." );753 assertf( ! options.genC, "UntypedTupleExpr should not reach code generation." ); 747 754 extension( tupleExpr ); 748 755 output << "["; … … 752 759 753 760 void CodeGenerator::postvisit( TupleExpr * tupleExpr ) { 754 assertf( ! genC, "TupleExpr should not reach code generation." );761 assertf( ! options.genC, "TupleExpr should not reach code generation." ); 755 762 extension( tupleExpr ); 756 763 output << "["; … … 760 767 761 768 void CodeGenerator::postvisit( TupleIndexExpr * tupleExpr ) { 762 assertf( ! genC, "TupleIndexExpr should not reach code generation." );769 assertf( ! options.genC, "TupleIndexExpr should not reach code generation." ); 763 770 extension( tupleExpr ); 764 771 tupleExpr->get_tuple()->accept( *visitor ); … … 767 774 768 775 void CodeGenerator::postvisit( TypeExpr * typeExpr ) { 769 // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;770 // assertf( ! genC, "TypeExpr should not reach code generation." );771 if ( ! genC ) {772 output << genType( typeExpr->get_type(), "", pretty, genC);776 // if ( options.genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl; 777 // assertf( ! options.genC, "TypeExpr should not reach code generation." ); 778 if ( ! options.genC ) { 779 output << genType( typeExpr->get_type(), "", options ); 773 780 } 774 781 } … … 788 795 void CodeGenerator::postvisit( CompoundLiteralExpr *compLitExpr ) { 789 796 assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) ); 790 output << "(" << genType( compLitExpr->get_result(), "", pretty, genC) << ")";797 output << "(" << genType( compLitExpr->get_result(), "", options ) << ")"; 791 798 compLitExpr->get_initializer()->accept( *visitor ); 792 799 } 793 800 794 801 void CodeGenerator::postvisit( UniqueExpr * unqExpr ) { 795 assertf( ! genC, "Unique expressions should not reach code generation." );802 assertf( ! options.genC, "Unique expressions should not reach code generation." ); 796 803 output << "unq<" << unqExpr->get_id() << ">{ "; 797 804 unqExpr->get_expr()->accept( *visitor ); … … 829 836 830 837 void CodeGenerator::postvisit( ConstructorExpr * expr ) { 831 assertf( ! genC, "Unique expressions should not reach code generation." );838 assertf( ! options.genC, "Unique expressions should not reach code generation." ); 832 839 expr->callExpr->accept( *visitor ); 833 840 } 834 841 835 842 void CodeGenerator::postvisit( DeletedExpr * expr ) { 836 assertf( ! genC, "Deleted expressions should not reach code generation." );843 assertf( ! options.genC, "Deleted expressions should not reach code generation." ); 837 844 expr->expr->accept( *visitor ); 838 845 } 839 846 840 847 void CodeGenerator::postvisit( DefaultArgExpr * arg ) { 841 assertf( ! genC, "Default argument expressions should not reach code generation." );848 assertf( ! options.genC, "Default argument expressions should not reach code generation." ); 842 849 arg->expr->accept( *visitor ); 843 850 } 844 851 845 852 void CodeGenerator::postvisit( GenericExpr * expr ) { 846 assertf( ! genC, "C11 _Generic expressions should not reach code generation." );853 assertf( ! options.genC, "C11 _Generic expressions should not reach code generation." ); 847 854 output << "_Generic("; 848 855 expr->control->accept( *visitor ); … … 854 861 output << "default: "; 855 862 } else { 856 output << genType( assoc.type, "", pretty, genC) << ": ";863 output << genType( assoc.type, "", options ) << ": "; 857 864 } 858 865 assoc.expr->accept( *visitor ); … … 889 896 void CodeGenerator::postvisit( ExprStmt * exprStmt ) { 890 897 assert( exprStmt ); 891 if ( genC ) {898 if ( options.genC ) { 892 899 // cast the top-level expression to void to reduce gcc warnings. 893 900 exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) ); … … 999 1006 case BranchStmt::FallThrough: 1000 1007 case BranchStmt::FallThroughDefault: 1001 assertf( ! genC, "fallthru should not reach code generation." );1008 assertf( ! options.genC, "fallthru should not reach code generation." ); 1002 1009 output << "fallthru"; 1003 1010 break; 1004 1011 } // switch 1005 1012 // print branch target for labelled break/continue/fallthru in debug mode 1006 if ( ! genC && branchStmt->get_type() != BranchStmt::Goto ) {1013 if ( ! options.genC && branchStmt->get_type() != BranchStmt::Goto ) { 1007 1014 if ( ! branchStmt->get_target().empty() ) { 1008 1015 output << " " << branchStmt->get_target(); … … 1021 1028 1022 1029 void CodeGenerator::postvisit( ThrowStmt * throwStmt ) { 1023 assertf( ! genC, "Throw statements should not reach code generation." );1030 assertf( ! options.genC, "Throw statements should not reach code generation." ); 1024 1031 1025 1032 output << ((throwStmt->get_kind() == ThrowStmt::Terminate) ? … … 1036 1043 } 1037 1044 void CodeGenerator::postvisit( CatchStmt * stmt ) { 1038 assertf( ! genC, "Catch statements should not reach code generation." );1045 assertf( ! options.genC, "Catch statements should not reach code generation." ); 1039 1046 1040 1047 output << ((stmt->get_kind() == CatchStmt::Terminate) ? … … 1053 1060 1054 1061 void CodeGenerator::postvisit( WaitForStmt * stmt ) { 1055 assertf( ! genC, "Waitfor statements should not reach code generation." );1062 assertf( ! options.genC, "Waitfor statements should not reach code generation." ); 1056 1063 1057 1064 bool first = true; … … 1099 1106 1100 1107 void CodeGenerator::postvisit( WithStmt * with ) { 1101 if ( ! genC ) {1108 if ( ! options.genC ) { 1102 1109 output << "with ( "; 1103 1110 genCommaList( with->exprs.begin(), with->exprs.end() ); … … 1165 1172 1166 1173 void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) { 1167 assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." );1174 assertf( ! options.genC, "ImplicitCtorDtorStmts should not reach code generation." ); 1168 1175 stmt->callStmt->accept( *visitor ); 1169 1176 } -
src/CodeGen/CodeGenerator.h
rec28948 r02af79b0 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 18 15:40:00 201713 // Update Count : 5 612 // Last Modified On : Tue Apr 30 12:01:00 2019 13 // Update Count : 57 14 14 // 15 15 … … 20 20 #include <string> // for string 21 21 22 #include "CodeGen/Options.h" // for Options 22 23 #include "Common/Indenter.h" // for Indenter 23 24 #include "Common/PassVisitor.h" // for PassVisitor … … 31 32 32 33 CodeGenerator( std::ostream &os, bool pretty = false, bool genC = false, bool lineMarks = false, bool printExprTypes = false ); 34 CodeGenerator( std::ostream &os, const Options &options ); 33 35 34 36 //*** Turn off visit_children for all nodes … … 144 146 std::ostream & output; 145 147 LabelPrinter printLabels; 146 bool pretty = false; // pretty print 147 bool genC = false; // true if output has to be C code 148 bool lineMarks = false; 149 bool printExprTypes = false; 148 Options options; 150 149 public: 151 150 LineEnder endl; -
src/CodeGen/GenType.cc
rec28948 r02af79b0 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Mar 17 09:02:28 201713 // Update Count : 2 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed May 1 15:24:00 2019 13 // Update Count : 23 14 14 // 15 15 #include "GenType.h" … … 28 28 struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting { 29 29 std::string typeString; 30 GenType( const std::string &typeString, bool pretty, bool genC, bool lineMarks );30 GenType( const std::string &typeString, const Options &options ); 31 31 32 32 void previsit( BaseSyntaxNode * ); … … 57 57 void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ); 58 58 59 bool pretty = false; // pretty print 60 bool genC = false; // generating C code? 61 bool lineMarks = false; // lineMarks on for CodeGenerator? 59 Options options; 62 60 }; 63 61 64 std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) {65 PassVisitor<GenType> gt( baseString, pretty, genC, lineMarks );62 std::string genType( Type *type, const std::string &baseString, const Options &options ) { 63 PassVisitor<GenType> gt( baseString, options ); 66 64 std::ostringstream os; 67 65 68 66 if ( ! type->get_attributes().empty() ) { 69 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );67 PassVisitor<CodeGenerator> cg( os, options ); 70 68 cg.pass.genAttributes( type->get_attributes() ); 71 69 } // if … … 75 73 } 76 74 77 std::string genPrettyType( Type * type, const std::string & baseString ) { 78 return genType( type, baseString, true, false ); 79 } 80 81 GenType::GenType( const std::string &typeString, bool pretty, bool genC, bool lineMarks ) : typeString( typeString ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {} 75 std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) { 76 return genType( type, baseString, Options(pretty, genC, lineMarks, false ) ); 77 } 78 79 std::string genPrettyType( Type * type, const std::string & baseString ) { 80 return genType( type, baseString, true, false ); 81 } 82 83 GenType::GenType( const std::string &typeString, const Options &options ) : typeString( typeString ), options( options ) {} 82 84 83 85 // *** BaseSyntaxNode … … 133 135 } // if 134 136 if ( dimension != 0 ) { 135 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );137 PassVisitor<CodeGenerator> cg( os, options ); 136 138 dimension->accept( cg ); 137 139 } else if ( isVarLen ) { … … 167 169 void GenType::postvisit( ReferenceType * refType ) { 168 170 assert( refType->base != 0); 169 assertf( ! genC, "Reference types should not reach code generation." );171 assertf( ! options.genC, "Reference types should not reach code generation." ); 170 172 handleQualifiers( refType ); 171 173 typeString = "&" + typeString; … … 195 197 } // if 196 198 } else { 197 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );199 PassVisitor<CodeGenerator> cg( os, options ); 198 200 os << "(" ; 199 201 … … 215 217 216 218 // add forall 217 if( ! funcType->forall.empty() && ! genC ) {219 if( ! funcType->forall.empty() && ! options.genC ) { 218 220 // assertf( ! genC, "Aggregate type parameters should not reach code generation." ); 219 221 std::ostringstream os; 220 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );222 PassVisitor<CodeGenerator> cg( os, options ); 221 223 os << "forall("; 222 224 cg.pass.genCommaList( funcType->forall.begin(), funcType->forall.end() ); … … 229 231 if ( ! refType->parameters.empty() ) { 230 232 std::ostringstream os; 231 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );233 PassVisitor<CodeGenerator> cg( os, options ); 232 234 os << "("; 233 235 cg.pass.genCommaList( refType->parameters.begin(), refType->parameters.end() ); … … 240 242 void GenType::postvisit( StructInstType * structInst ) { 241 243 typeString = structInst->name + handleGeneric( structInst ) + " " + typeString; 242 if ( genC ) typeString = "struct " + typeString;244 if ( options.genC ) typeString = "struct " + typeString; 243 245 handleQualifiers( structInst ); 244 246 } … … 246 248 void GenType::postvisit( UnionInstType * unionInst ) { 247 249 typeString = unionInst->name + handleGeneric( unionInst ) + " " + typeString; 248 if ( genC ) typeString = "union " + typeString;250 if ( options.genC ) typeString = "union " + typeString; 249 251 handleQualifiers( unionInst ); 250 252 } … … 252 254 void GenType::postvisit( EnumInstType * enumInst ) { 253 255 typeString = enumInst->name + " " + typeString; 254 if ( genC ) typeString = "enum " + typeString;256 if ( options.genC ) typeString = "enum " + typeString; 255 257 handleQualifiers( enumInst ); 256 258 } … … 262 264 263 265 void GenType::postvisit( TupleType * tupleType ) { 264 assertf( ! genC, "Tuple types should not reach code generation." );266 assertf( ! options.genC, "Tuple types should not reach code generation." ); 265 267 unsigned int i = 0; 266 268 std::ostringstream os; … … 268 270 for ( Type * t : *tupleType ) { 269 271 i++; 270 os << genType( t, "", pretty, genC, lineMarks ) << (i == tupleType->size() ? "" : ", ");272 os << genType( t, "", options ) << (i == tupleType->size() ? "" : ", "); 271 273 } 272 274 os << "] "; … … 281 283 void GenType::postvisit( ZeroType * zeroType ) { 282 284 // ideally these wouldn't hit codegen at all, but should be safe to make them ints 283 typeString = ( pretty ? "zero_t " : "long int ") + typeString;285 typeString = (options.pretty ? "zero_t " : "long int ") + typeString; 284 286 handleQualifiers( zeroType ); 285 287 } … … 287 289 void GenType::postvisit( OneType * oneType ) { 288 290 // ideally these wouldn't hit codegen at all, but should be safe to make them ints 289 typeString = ( pretty ? "one_t " : "long int ") + typeString;291 typeString = (options.pretty ? "one_t " : "long int ") + typeString; 290 292 handleQualifiers( oneType ); 291 293 } 292 294 293 295 void GenType::postvisit( GlobalScopeType * globalType ) { 294 assertf( ! genC, "Global scope type should not reach code generation." );296 assertf( ! options.genC, "Global scope type should not reach code generation." ); 295 297 handleQualifiers( globalType ); 296 298 } 297 299 298 300 void GenType::postvisit( TraitInstType * inst ) { 299 assertf( ! genC, "Trait types should not reach code generation." );301 assertf( ! options.genC, "Trait types should not reach code generation." ); 300 302 typeString = inst->name + " " + typeString; 301 303 handleQualifiers( inst ); … … 304 306 void GenType::postvisit( TypeofType * typeof ) { 305 307 std::ostringstream os; 306 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );308 PassVisitor<CodeGenerator> cg( os, options ); 307 309 os << "typeof("; 308 310 typeof->expr->accept( cg ); … … 313 315 314 316 void GenType::postvisit( QualifiedType * qualType ) { 315 assertf( ! genC, "Qualified types should not reach code generation." );316 std::ostringstream os; 317 os << genType( qualType->parent, "", pretty, genC, lineMarks ) << "." << genType( qualType->child, "", pretty, genC, lineMarks ) << typeString;317 assertf( ! options.genC, "Qualified types should not reach code generation." ); 318 std::ostringstream os; 319 os << genType( qualType->parent, "", options ) << "." << genType( qualType->child, "", options ) << typeString; 318 320 typeString = os.str(); 319 321 handleQualifiers( qualType ); … … 333 335 typeString = "_Atomic " + typeString; 334 336 } // if 335 if ( type->get_lvalue() && ! genC ) {337 if ( type->get_lvalue() && ! options.genC ) { 336 338 // when not generating C code, print lvalue for debugging. 337 339 typeString = "lvalue " + typeString; -
src/CodeGen/GenType.h
rec28948 r02af79b0 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Jul 21 22:17:23 201713 // Update Count : 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Apr 30 11:47:00 2019 13 // Update Count : 3 14 14 // 15 15 … … 18 18 #include <string> // for string 19 19 20 #include "CodeGen/Options.h" // for Options 21 20 22 class Type; 21 23 22 24 namespace CodeGen { 25 std::string genType( Type *type, const std::string &baseString, const Options &options ); 23 26 std::string genType( Type *type, const std::string &baseString, bool pretty = false, bool genC = false, bool lineMarks = false ); 24 27 std::string genPrettyType( Type * type, const std::string & baseString ); -
src/Common/Assert.cc
rec28948 r02af79b0 39 39 } 40 40 41 void abort(const char *fmt, ... ) noexcept __attribute__((noreturn, format(printf, 1, 2))); 42 void abort(const char *fmt, ... ) noexcept { 43 va_list args; 44 va_start( args, fmt ); 45 vfprintf( stderr, fmt, args ); 46 va_end( args ); 47 fprintf( stderr, "\n" ); 48 abort(); 49 } 50 41 51 // Local Variables: // 42 52 // tab-width: 4 // -
src/Common/PassVisitor.h
rec28948 r02af79b0 4 4 5 5 #include <stack> 6 #include <type_traits> 6 7 7 8 #include "Common/Stats.h" … … 301 302 302 303 303 TypeSubstitution ** get_env_ptr () { return env_impl( pass, 0); }304 auto get_env_ptr () -> decltype(env_impl( pass, 0)) { return env_impl( pass, 0); } 304 305 std::list< Statement* > * get_beforeStmts() { return stmtsToAddBefore_impl( pass, 0); } 305 306 std::list< Statement* > * get_afterStmts () { return stmtsToAddAfter_impl ( pass, 0); } … … 348 349 }; 349 350 351 class WithConstTypeSubstitution { 352 protected: 353 WithConstTypeSubstitution() = default; 354 ~WithConstTypeSubstitution() = default; 355 356 public: 357 const TypeSubstitution * env = nullptr; 358 }; 359 350 360 class WithStmtsToAdd { 351 361 protected: -
src/Common/PassVisitor.impl.h
rec28948 r02af79b0 20 20 21 21 #define MUTATE_END( type, node ) \ 22 return call_postmutate< type * >( node ); \ 22 auto __return = call_postmutate< type * >( node ); \ 23 assert( __return ); \ 24 return __return; 23 25 24 26 … … 253 255 254 256 // don't want statements from outer CompoundStmts to be added to this CompoundStmt 255 ValueGuardPtr< TypeSubstitution * > oldEnv ( get_env_ptr() );257 ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type > oldEnv( get_env_ptr() ); 256 258 ValueGuardPtr< DeclList_t > oldBeforeDecls( get_beforeDecls() ); 257 259 ValueGuardPtr< DeclList_t > oldAfterDecls ( get_afterDecls () ); … … 1995 1997 1996 1998 // don't want statements from outer CompoundStmts to be added to this StmtExpr 1997 ValueGuardPtr< TypeSubstitution * > oldEnv( get_env_ptr() );1999 ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type > oldEnv( get_env_ptr() ); 1998 2000 ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() ); 1999 2001 ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () ); … … 2012 2014 2013 2015 // don't want statements from outer CompoundStmts to be added to this StmtExpr 2014 ValueGuardPtr< TypeSubstitution * > oldEnv( get_env_ptr() );2016 ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type > oldEnv( get_env_ptr() ); 2015 2017 ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() ); 2016 2018 ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () ); -
src/Common/PassVisitor.proto.h
rec28948 r02af79b0 165 165 static inline type * name##_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) { return nullptr;} \ 166 166 167 FIELD_PTR( TypeSubstitution *, env )167 FIELD_PTR( const TypeSubstitution *, env ) 168 168 FIELD_PTR( std::list< Statement* >, stmtsToAddBefore ) 169 169 FIELD_PTR( std::list< Statement* >, stmtsToAddAfter ) … … 174 174 FIELD_PTR( PassVisitor<pass_type> * const, visitor ) 175 175 176 #undef FIELD_PTR 177 176 178 //--------------------------------------------------------- 177 179 // Indexer -
src/CompilationState.cc
rec28948 r02af79b0 9 9 // Author : Rob Schluntz 10 10 // Created On : Mon Ju1 30 10:47:01 2018 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Mon Ju1 30 10:46:25 201813 // Update Count : 211 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri May 3 13:45:23 2019 13 // Update Count : 4 14 14 // 15 15 16 bool 16 int 17 17 astp = false, 18 18 bresolvep = false, … … 26 26 libcfap = false, 27 27 nopreludep = false, 28 noprotop= false,28 genproto = false, 29 29 nomainp = false, 30 30 parsep = false, -
src/CompilationState.h
rec28948 r02af79b0 9 9 // Author : Rob Schluntz 10 10 // Created On : Mon Ju1 30 10:47:01 2018 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Mon Ju1 30 10:46:25 201813 // Update Count : 211 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri May 3 13:43:21 2019 13 // Update Count : 4 14 14 // 15 15 16 16 extern int yydebug; // set for -g flag (Grammar) 17 extern bool17 extern int 18 18 astp, 19 19 bresolvep, … … 27 27 libcfap, 28 28 nopreludep, 29 noprotop,29 genproto, 30 30 nomainp, 31 31 parsep, -
src/ControlStruct/ExceptTranslate.cc
rec28948 r02af79b0 617 617 return create_terminate_rethrow( throwStmt ); 618 618 } else { 619 a ssertf(false,"Invalid throw in %s at %i\n",619 abort("Invalid throw in %s at %i\n", 620 620 throwStmt->location.filename.c_str(), 621 621 throwStmt->location.first_line); 622 return nullptr;623 622 } 624 623 } else { … … 628 627 return create_resume_rethrow( throwStmt ); 629 628 } else { 630 a ssertf(false,"Invalid throwResume in %s at %i\n",629 abort("Invalid throwResume in %s at %i\n", 631 630 throwStmt->location.filename.c_str(), 632 631 throwStmt->location.first_line); 633 return nullptr;634 632 } 635 633 } -
src/GenPoly/Box.cc
rec28948 r02af79b0 76 76 77 77 /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call 78 class Pass1 final : public BoxPass, public With TypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {78 class Pass1 final : public BoxPass, public WithConstTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting { 79 79 public: 80 80 Pass1(); … … 150 150 /// * Calculates polymorphic offsetof expressions from offset array 151 151 /// * Inserts dynamic calculation of polymorphic type layouts where needed 152 class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public With TypeSubstitution {152 class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithConstTypeSubstitution { 153 153 public: 154 154 PolyGenericCalculator(); … … 1764 1764 1765 1765 Expression *PolyGenericCalculator::postmutate( SizeofExpr *sizeofExpr ) { 1766 Type *ty = sizeofExpr->get_isType() ? 1766 Type *ty = sizeofExpr->get_isType() ? 1767 1767 sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result(); 1768 1768 1769 1769 Expression * gen = genSizeof( ty ); 1770 1770 if ( gen ) { -
src/GenPoly/GenPoly.cc
rec28948 r02af79b0 440 440 } 441 441 442 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env ) {442 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) { 443 443 // is parameter is not polymorphic, don't need to box 444 444 if ( ! isPolyType( param, exprTyVars ) ) return false; … … 450 450 } 451 451 452 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env ) {452 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) { 453 453 FunctionType * function = getFunctionType( appExpr->function->result ); 454 454 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() ); -
src/GenPoly/GenPoly.h
rec28948 r02af79b0 81 81 82 82 /// true if arg requires boxing given exprTyVars 83 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env );83 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ); 84 84 85 85 /// true if arg requires boxing in the call to appExpr 86 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env );86 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ); 87 87 88 88 /// Adds the type variable `tyVar` to `tyVarMap` -
src/GenPoly/InstantiateGeneric.cc
rec28948 r02af79b0 168 168 169 169 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 170 struct GenericInstantiator final : public With TypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards {170 struct GenericInstantiator final : public WithConstTypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards { 171 171 /// Map of (generic type, parameter list) pairs to concrete type instantiations 172 172 InstantiationMap< AggregateDecl, AggregateDecl > instantiations; -
src/GenPoly/Specialize.cc
rec28948 r02af79b0 42 42 43 43 namespace GenPoly { 44 struct Specialize final : public With TypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> {44 struct Specialize final : public WithConstTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> { 45 45 Expression * postmutate( ApplicationExpr *applicationExpr ); 46 46 Expression * postmutate( CastExpr *castExpr ); … … 54 54 55 55 /// Looks up open variables in actual type, returning true if any of them are bound in the environment or formal type. 56 bool needsPolySpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {56 bool needsPolySpecialization( Type *formalType, Type *actualType, const TypeSubstitution *env ) { 57 57 if ( env ) { 58 58 using namespace ResolvExpr; … … 145 145 } 146 146 147 bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {147 bool needsSpecialization( Type *formalType, Type *actualType, const TypeSubstitution *env ) { 148 148 return needsPolySpecialization( formalType, actualType, env ) || needsTupleSpecialization( formalType, actualType ); 149 149 } -
src/InitTweak/FixInit.cc
rec28948 r02af79b0 72 72 }; 73 73 74 struct InsertImplicitCalls : public With TypeSubstitution {74 struct InsertImplicitCalls : public WithConstTypeSubstitution { 75 75 /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which 76 76 /// function calls need their parameters to be copy constructed … … 187 187 }; 188 188 189 class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors>, public With TypeSubstitution {189 class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors>, public WithConstTypeSubstitution { 190 190 public: 191 191 FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){} -
src/ResolvExpr/ConversionCost.cc
rec28948 r02af79b0 10 10 // Created On : Sun May 17 07:06:19 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 26 16:33:04201913 // Update Count : 2 412 // Last Modified On : Mon May 6 14:18:22 2019 13 // Update Count : 25 14 14 // 15 15 … … 249 249 /*_FLDXC*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, }, 250 250 }; // costMatrix 251 static const int maxIntCost = 15; 251 252 // GENERATED END 252 253 static_assert( … … 461 462 } // if 462 463 } else if ( dynamic_cast< PointerType* >( dest ) ) { 463 cost = Cost::safe; 464 cost = Cost::zero; 465 cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation 464 466 } // if 465 467 } -
src/ResolvExpr/RenameVars.cc
rec28948 r02af79b0 10 10 // Created On : Sun May 17 12:05:18 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:36:32 201613 // Update Count : 512 // Last Modified On : Tue Apr 30 17:07:57 2019 13 // Update Count : 7 14 14 // 15 15 … … 39 39 private: 40 40 int level, resetCount; 41 std::list< std:: map< std::string, std::string > > mapStack;41 std::list< std::unordered_map< std::string, std::string > > mapStack; 42 42 }; 43 43 … … 55 55 namespace { 56 56 RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) { 57 mapStack.push_front( std:: map< std::string, std::string >() );57 mapStack.push_front( std::unordered_map< std::string, std::string >() ); 58 58 } 59 59 … … 65 65 void RenameVars::previsit( TypeInstType * instType ) { 66 66 previsit( (Type *)instType ); 67 std:: map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->name );67 std::unordered_map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->name ); 68 68 if ( i != mapStack.front().end() ) { 69 69 instType->name = i->second; -
src/ResolvExpr/TypeEnvironment.h
rec28948 r02af79b0 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:24:58 2015 11 // Last Modified By : Aaron B. Moss12 // Last Modified On : Mon Jun 18 11:58:00 201813 // Update Count : 411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Apr 30 23:04:10 2019 13 // Update Count : 9 14 14 // 15 15 … … 18 18 #include <iostream> // for ostream 19 19 #include <list> // for list, list<>::iterator, list<>... 20 #include <map> // for map, map<>::value_compare 21 #include <set> // for set 20 #include <map> // for map, map<>::value_compare 21 #include <unordered_map> 22 #include <set> // for set 22 23 #include <string> // for string 23 24 #include <utility> // for move, swap … … 64 65 AssertionSetValue() : isUsed(false), resnSlot(0) {} 65 66 }; 66 typedef std::map< DeclarationWithType *, AssertionSetValue, AssertCompare > AssertionSet;67 typedef std:: map< std::string, TypeDecl::Data > OpenVarSet;67 typedef std::map< DeclarationWithType *, AssertionSetValue, AssertCompare > AssertionSet; 68 typedef std::unordered_map< std::string, TypeDecl::Data > OpenVarSet; 68 69 69 70 /// merges one set of open vars into another -
src/SynTree/Declaration.h
rec28948 r02af79b0 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sun Sep 3 19:24:06 201713 // Update Count : 13 111 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr May 2 10:47:00 2019 13 // Update Count : 135 14 14 // 15 15 … … 19 19 #include <iosfwd> // for ostream 20 20 #include <list> // for list 21 #include <unordered_map> // for unordered_map 21 22 #include <string> // for string, operator+, allocator, to_string 22 23 … … 166 167 CompoundStmt *get_statements() const { return statements; } 167 168 void set_statements( CompoundStmt *newValue ) { statements = newValue; } 169 bool has_body() const { return NULL != statements; } 168 170 169 171 static FunctionDecl * newFunction( const std::string & name, FunctionType * type, CompoundStmt * statements ); … … 334 336 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 335 337 private: 336 std:: map< std::string, long long int > enumValues;338 std::unordered_map< std::string, long long int > enumValues; 337 339 virtual std::string typeString() const override; 338 340 }; -
src/SynTree/TypeSubstitution.cc
rec28948 r02af79b0 108 108 namespace { 109 109 struct EnvTrimmer { 110 TypeSubstitution * env, * newEnv; 111 EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){} 110 const TypeSubstitution * env; 111 TypeSubstitution * newEnv; 112 EnvTrimmer( const TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){} 112 113 void previsit( TypeDecl * tyDecl ) { 113 114 // transfer known bindings for seen type variables … … 120 121 121 122 /// reduce environment to just the parts that are referenced in a given expression 122 TypeSubstitution * TypeSubstitution::newFromExpr( Expression * expr, TypeSubstitution * env ) {123 TypeSubstitution * TypeSubstitution::newFromExpr( Expression * expr, const TypeSubstitution * env ) { 123 124 if ( env ) { 124 125 TypeSubstitution * newEnv = new TypeSubstitution(); -
src/SynTree/TypeSubstitution.h
rec28948 r02af79b0 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:52:24 201713 // Update Count : 312 // Last Modified On : Tue Apr 30 22:52:47 2019 13 // Update Count : 9 14 14 // 15 15 … … 19 19 #include <iosfwd> // for ostream 20 20 #include <list> // for list<>::iterator, _List_iterator 21 #include < map> // for _Rb_tree_iterator, map, map<>::val...22 #include < set> // for set21 #include <unordered_map> 22 #include <unordered_set> 23 23 #include <string> // for string, operator!= 24 24 #include <utility> // for pair … … 39 39 TypeSubstitution &operator=( const TypeSubstitution &other ); 40 40 41 template< typename SynTreeClass > int apply( SynTreeClass *&input ) ;42 template< typename SynTreeClass > int applyFree( SynTreeClass *&input ) ;41 template< typename SynTreeClass > int apply( SynTreeClass *&input ) const; 42 template< typename SynTreeClass > int applyFree( SynTreeClass *&input ) const; 43 43 44 44 void add( std::string formalType, Type *actualType ); … … 56 56 57 57 /// create a new TypeSubstitution using bindings from env containing all of the type variables in expr 58 static TypeSubstitution * newFromExpr( Expression * expr, TypeSubstitution * env );58 static TypeSubstitution * newFromExpr( Expression * expr, const TypeSubstitution * env ); 59 59 60 60 void normalize(); … … 78 78 friend class PassVisitor; 79 79 80 typedef std:: map< std::string, Type* > TypeEnvType;81 typedef std:: map< std::string, Expression* > VarEnvType;80 typedef std::unordered_map< std::string, Type * > TypeEnvType; 81 typedef std::unordered_map< std::string, Expression * > VarEnvType; 82 82 TypeEnvType typeEnv; 83 83 VarEnvType varEnv; … … 98 98 ActualIterator actualIt = actualBegin; 99 99 for ( ; formalIt != formalEnd; ++formalIt, ++actualIt ) { 100 if ( TypeDecl *formal = dynamic_cast< TypeDecl * >( *formalIt ) ) {101 if ( TypeExpr *actual = dynamic_cast< TypeExpr * >( *actualIt ) ) {100 if ( TypeDecl *formal = dynamic_cast< TypeDecl * >( *formalIt ) ) { 101 if ( TypeExpr *actual = dynamic_cast< TypeExpr * >( *actualIt ) ) { 102 102 if ( formal->get_name() != "" ) { 103 103 TypeEnvType::iterator i = typeEnv.find( formal->get_name() ); … … 130 130 // definitition must happen after PassVisitor is included so that WithGuards can be used 131 131 struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef<Substituter> { 132 Substituter( TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {}132 Substituter( const TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {} 133 133 134 134 Type * postmutate( TypeInstType * aggregateUseType ); … … 143 143 void premutate( UnionInstType * aggregateUseType ); 144 144 145 TypeSubstitution & sub;145 const TypeSubstitution & sub; 146 146 int subCount = 0; 147 147 bool freeOnly; 148 typedef std:: set< std::string > BoundVarsType;148 typedef std::unordered_set< std::string > BoundVarsType; 149 149 BoundVarsType boundVars; 150 150 }; 151 151 152 152 template< typename SynTreeClass > 153 int TypeSubstitution::apply( SynTreeClass *&input ) {153 int TypeSubstitution::apply( SynTreeClass *&input ) const { 154 154 assert( input ); 155 155 PassVisitor<Substituter> sub( *this, false ); … … 163 163 164 164 template< typename SynTreeClass > 165 int TypeSubstitution::applyFree( SynTreeClass *&input ) {165 int TypeSubstitution::applyFree( SynTreeClass *&input ) const { 166 166 assert( input ); 167 167 PassVisitor<Substituter> sub( *this, true ); -
src/Tuples/TupleExpansion.cc
rec28948 r02af79b0 58 58 }; 59 59 60 struct TupleTypeReplacer : public WithDeclsToAdd, public WithGuards, public With TypeSubstitution {60 struct TupleTypeReplacer : public WithDeclsToAdd, public WithGuards, public WithConstTypeSubstitution { 61 61 Type * postmutate( TupleType * tupleType ); 62 62 -
src/include/cassert
rec28948 r02af79b0 45 45 } 46 46 47 extern void abort(const char *fmt, ... ) noexcept __attribute__((noreturn, format(printf, 1, 2))); 47 48 // Local Variables: // 48 49 // tab-width: 4 // -
src/main.cc
rec28948 r02af79b0 7 7 // main.cc -- 8 8 // 9 // Author : Richard C. Bilson9 // Author : Peter Buhr and Rob Schluntz 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Feb 16 09:14:04201913 // Update Count : 5 0012 // Last Modified On : Fri May 3 16:10:52 2019 13 // Update Count : 599 14 14 // 15 15 … … 24 24 #include <fstream> // for ofstream 25 25 #include <iostream> // for operator<<, basic_ostream 26 #include <iomanip> 26 27 #include <iterator> // for back_inserter 27 28 #include <list> // for list … … 39 40 #include "Common/Stats.h" 40 41 #include "Common/PassVisitor.h" 42 // #include "AST/Pass.hpp" 41 43 #include "Common/SemanticError.h" // for SemanticError 42 44 #include "Common/UnimplementedError.h" // for UnimplementedError … … 65 67 using namespace std; 66 68 67 void NewPass(const char * const name) {68 Stats::Heap::newPass( name);69 static void NewPass( const char * const name ) { 70 Stats::Heap::newPass( name ); 69 71 using namespace Stats::Counters; 70 71 72 { 72 static auto group = build<CounterGroup>( "Pass Visitor");73 auto pass = build<CounterGroup>( name, group);73 static auto group = build<CounterGroup>( "Pass Visitor" ); 74 auto pass = build<CounterGroup>( name, group ); 74 75 pass_visitor_stats.depth = 0; 75 pass_visitor_stats.avg = build<AverageCounter<double>>( "Average Depth", pass);76 pass_visitor_stats.max = build<MaxCounter<double>>( "Max Depth", pass);76 pass_visitor_stats.avg = build<AverageCounter<double>>( "Average Depth", pass ); 77 pass_visitor_stats.max = build<MaxCounter<double>>( "Max Depth", pass ); 77 78 } 78 79 79 { 80 static auto group = build<CounterGroup>( "Syntax Node");81 auto pass = build<CounterGroup>( name, group);82 BaseSyntaxNode::new_nodes = build<SimpleCounter>( "Allocs", pass);80 static auto group = build<CounterGroup>( "Syntax Node" ); 81 auto pass = build<CounterGroup>( name, group ); 82 BaseSyntaxNode::new_nodes = build<SimpleCounter>( "Allocs", pass ); 83 83 } 84 84 } 85 85 86 #define PASS( name, pass) \86 #define PASS( name, pass ) \ 87 87 if ( errorp ) { cerr << name << endl; } \ 88 88 NewPass(name); \ … … 95 95 DeclarationNode * parseTree = nullptr; // program parse tree 96 96 97 st d::string PreludeDirector = "";97 static std::string PreludeDirector = ""; 98 98 99 99 static void parse_cmdline( int argc, char *argv[], const char *& filename ); … … 151 151 } // backtrace 152 152 153 void sigSegvBusHandler( int sig_num ) {153 static void sigSegvBusHandler( int sig_num ) { 154 154 cerr << "*CFA runtime error* program cfa-cpp terminated with " 155 155 << (sig_num == SIGSEGV ? "segment fault" : "bus error") … … 157 157 backtrace( 2 ); // skip first 2 stack frames 158 158 //_exit( EXIT_FAILURE ); 159 abort(); 159 abort(); // cause core dump for debugging 160 160 } // sigSegvBusHandler 161 161 162 void sigAbortHandler( __attribute__((unused)) int sig_num ) {162 static void sigAbortHandler( __attribute__((unused)) int sig_num ) { 163 163 backtrace( 6 ); // skip first 6 stack frames 164 164 signal( SIGABRT, SIG_DFL); // reset default signal handler … … 240 240 parseTree->printList( cout ); 241 241 delete parseTree; 242 return 0;242 return EXIT_SUCCESS; 243 243 } // if 244 244 … … 249 249 if ( astp ) { 250 250 dump( translationUnit ); 251 return 0;251 return EXIT_SUCCESS; 252 252 } // if 253 253 … … 262 262 if ( symtabp ) { 263 263 deleteAll( translationUnit ); 264 return 0;264 return EXIT_SUCCESS; 265 265 } // if 266 266 … … 268 268 PassVisitor<ResolvExpr::AlternativePrinter> printer( cout ); 269 269 acceptAll( translationUnit, printer ); 270 return 0;270 return EXIT_SUCCESS; 271 271 } // if 272 272 273 273 if ( validp ) { 274 274 dump( translationUnit ); 275 return 0;275 return EXIT_SUCCESS; 276 276 } // if 277 277 … … 288 288 CodeTools::printDeclStats( translationUnit ); 289 289 deleteAll( translationUnit ); 290 return 0;291 } 290 return EXIT_SUCCESS; 291 } // if 292 292 293 293 if ( bresolvep ) { 294 294 dump( translationUnit ); 295 return 0;295 return EXIT_SUCCESS; 296 296 } // if 297 297 … … 300 300 if ( resolvprotop ) { 301 301 CodeTools::dumpAsResolvProto( translationUnit ); 302 return 0;303 } 302 return EXIT_SUCCESS; 303 } // if 304 304 305 305 PASS( "Resolve", ResolvExpr::resolve( translationUnit ) ); 306 306 if ( exprp ) { 307 307 dump( translationUnit ); 308 return 0;308 return EXIT_SUCCESS; 309 309 } // if 310 310 … … 313 313 if ( ctorinitp ) { 314 314 dump ( translationUnit ); 315 return 0;315 return EXIT_SUCCESS; 316 316 } // if 317 317 … … 328 328 if ( tuplep ) { 329 329 dump( translationUnit ); 330 return 0;331 } 330 return EXIT_SUCCESS; 331 } // if 332 332 333 333 PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM … … 336 336 if ( genericsp ) { 337 337 dump( translationUnit ); 338 return 0;339 } 338 return EXIT_SUCCESS; 339 } // if 340 340 PASS( "Convert L-Value", GenPoly::convertLvalue( translationUnit ) ); 341 341 … … 343 343 if ( bboxp ) { 344 344 dump( translationUnit ); 345 return 0;345 return EXIT_SUCCESS; 346 346 } // if 347 347 PASS( "Box", GenPoly::box( translationUnit ) ); … … 349 349 if ( bcodegenp ) { 350 350 dump( translationUnit ); 351 return 0;352 } 351 return EXIT_SUCCESS; 352 } // if 353 353 354 354 if ( optind < argc ) { // any commands after the flags and input file ? => output file name … … 357 357 358 358 CodeTools::fillLocations( translationUnit ); 359 PASS( "Code Gen", CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp, true, linemarks ) );359 PASS( "Code Gen", CodeGen::generate( translationUnit, *output, ! genproto, prettycodegenp, true, linemarks ) ); 360 360 361 361 CodeGen::FixMain::fix( *output, (PreludeDirector + "/bootloader.c").c_str() ); … … 373 373 delete output; 374 374 } // if 375 return 1;375 return EXIT_FAILURE; 376 376 } catch ( UnimplementedError &e ) { 377 377 cout << "Sorry, " << e.get_what() << " is not currently implemented" << endl; … … 379 379 delete output; 380 380 } // if 381 return 1;381 return EXIT_FAILURE; 382 382 } catch ( CompilerError &e ) { 383 383 cerr << "Compiler Error: " << e.get_what() << endl; … … 386 386 delete output; 387 387 } // if 388 return 1;389 } catch (...) {388 return EXIT_FAILURE; 389 } catch ( ... ) { 390 390 std::exception_ptr eptr = std::current_exception(); 391 391 try { 392 392 if (eptr) { 393 393 std::rethrow_exception(eptr); 394 } 395 else { 396 std::cerr << "Exception Uncaught and Unkown" << std::endl; 397 } 394 } else { 395 std::cerr << "Exception Uncaught and Unknown" << std::endl; 396 } // if 398 397 } catch(const std::exception& e) { 399 398 std::cerr << "Uncaught Exception \"" << e.what() << "\"\n"; 400 } 401 return 1;402 } // try399 } // try 400 return EXIT_FAILURE; 401 } // try 403 402 404 403 deleteAll( translationUnit ); 405 404 Stats::print(); 406 407 return 0; 405 return EXIT_SUCCESS; 408 406 } // main 409 407 410 void parse_cmdline( int argc, char * argv[], const char *& filename ) { 411 enum { Ast, Bbox, Bresolver, CtorInitFix, DeclStats, Expr, ExprAlt, Grammar, LibCFA, Linemarks, Nolinemarks, Nopreamble, Parse, PreludeDir, Prototypes, Resolver, ResolvProto, Stats, Symbol, Tree, TupleExpansion, Validate}; 412 413 static struct option long_opts[] = { 414 { "ast", no_argument, 0, Ast }, 415 { "before-box", no_argument, 0, Bbox }, 416 { "before-resolver", no_argument, 0, Bresolver }, 417 { "ctorinitfix", no_argument, 0, CtorInitFix }, 418 { "decl-stats", no_argument, 0, DeclStats }, 419 { "expr", no_argument, 0, Expr }, 420 { "expralt", no_argument, 0, ExprAlt }, 421 { "grammar", no_argument, 0, Grammar }, 422 { "libcfa", no_argument, 0, LibCFA }, 423 { "line-marks", no_argument, 0, Linemarks }, 424 { "no-line-marks", no_argument, 0, Nolinemarks }, 425 { "no-preamble", no_argument, 0, Nopreamble }, 426 { "parse", no_argument, 0, Parse }, 427 { "prelude-dir", required_argument, 0, PreludeDir }, 428 { "no-prototypes", no_argument, 0, Prototypes }, 429 { "resolver", no_argument, 0, Resolver }, 430 { "resolv-proto", no_argument, 0, ResolvProto }, 431 { "stats", required_argument, 0, Stats }, 432 { "symbol", no_argument, 0, Symbol }, 433 { "tree", no_argument, 0, Tree }, 434 { "tuple-expansion", no_argument, 0, TupleExpansion }, 435 { "validate", no_argument, 0, Validate }, 436 { 0, 0, 0, 0 } 437 }; // long_opts 438 int long_index; 439 408 409 static const char optstring[] = ":hlLmNn:pP:S:twW:D:F:"; 410 411 enum { PreludeDir = 128 }; 412 static struct option long_opts[] = { 413 { "help", no_argument, nullptr, 'h' }, 414 { "libcfa", no_argument, nullptr, 'l' }, 415 { "linemarks", no_argument, nullptr, 'L' }, 416 { "no-main", no_argument, 0, 'm' }, 417 { "no-linemarks", no_argument, nullptr, 'N' }, 418 { "no-prelude", no_argument, nullptr, 'n' }, 419 { "prototypes", no_argument, nullptr, 'p' }, 420 { "print", required_argument, nullptr, 'P' }, 421 { "prelude-dir", required_argument, nullptr, PreludeDir }, 422 { "statistics", required_argument, nullptr, 'S' }, 423 { "tree", no_argument, nullptr, 't' }, 424 { "", no_argument, nullptr, 0 }, // -w 425 { "", no_argument, nullptr, 0 }, // -W 426 { "", no_argument, nullptr, 0 }, // -D 427 { "", no_argument, nullptr, 0 }, // -F 428 { nullptr, 0, nullptr, 0 } 429 }; // long_opts 430 431 static const char * description[] = { 432 "print help message", // -h 433 "generate libcfa.c", // -l 434 "generate line marks", // -L 435 "do not replace main", // -m 436 "do not generate line marks", // -N 437 "do not read prelude", // -n 438 "generate prototypes for prelude functions", // -p 439 "print", // -P 440 "<directory> prelude directory for debug/nodebug", // no flag 441 "<option-list> enable profiling information:\n counters,heap,time,all,none", // -S 442 "build in tree", // -t 443 "", // -w 444 "", // -W 445 "", // -D 446 "", // -F 447 }; // description 448 449 static_assert( sizeof( long_opts ) / sizeof( long_opts[0] ) - 1 == sizeof( description ) / sizeof( description[0] ), "Long opts and description must match" ); 450 451 static struct Printopts { 452 const char * name; 453 int & flag; 454 int val; 455 const char * descript; 456 } printopts[] = { 457 { "altexpr", expraltp, true, "alternatives for expressions" }, 458 { "ascodegen", codegenp, true, "as codegen rather than AST" }, 459 { "ast", astp, true, "AST after parsing" }, 460 { "astdecl", validp, true, "AST after declaration validation pass" }, 461 { "asterr", errorp, true, "AST on error" }, 462 { "astexpr", exprp, true, "AST after expression analysis" }, 463 { "astgen", genericsp, true, "AST after instantiate generics" }, 464 { "box", bboxp, true, "before box step" }, 465 { "ctordtor", ctorinitp, true, "after ctor/dtor are replaced" }, 466 { "codegen", bcodegenp, true, "before code generation" }, 467 { "declstats", declstatsp, true, "code property statistics" }, 468 { "parse", yydebug, true, "yacc (parsing) debug information" }, 469 { "pretty", prettycodegenp, true, "prettyprint for ascodegen flag" }, 470 { "resolver", bresolvep, true, "before resolver step" }, 471 { "rproto", resolvprotop, true, "resolver-proto instance" }, 472 { "rsteps", resolvep, true, "resolver steps" }, 473 { "symevt", symtabp, true, "symbol table events" }, 474 { "tree", parsep, true, "parse tree" }, 475 { "tuple", tuplep, true, "after tuple expansion" }, 476 }; 477 enum { printoptsSize = sizeof( printopts ) / sizeof( printopts[0] ) }; 478 479 static void usage( char *argv[] ) { 480 cout << "Usage: " << argv[0] << " options are:" << endl; 481 int i = 0, j = 1; // j skips starting colon 482 for ( ; long_opts[i].name != 0 && optstring[j] != '\0'; i += 1, j += 1 ) { 483 if ( long_opts[i].name[0] != '\0' ) { // hidden option, internal usage only 484 if ( strcmp( long_opts[i].name, "prelude-dir" ) != 0 ) { // flag 485 cout << " -" << optstring[j] << ","; 486 } else { // no flag 487 j -= 1; // compensate 488 cout << " "; 489 } // if 490 cout << " --" << left << setw(12) << long_opts[i].name << " "; 491 if ( strcmp( long_opts[i].name, "print" ) == 0 ) { 492 cout << "one of: " << endl; 493 for ( int i = 0; i < printoptsSize; i += 1 ) { 494 cout << setw(10) << " " << left << setw(10) << printopts[i].name << " " << printopts[i].descript << endl; 495 } // for 496 } else { 497 cout << description[i] << endl; 498 } // if 499 } // if 500 if ( optstring[j + 1] == ':' ) j += 1; 501 } // for 502 if ( long_opts[i].name != 0 || optstring[j] != '\0' ) assertf( false, "internal error, mismatch of option flags and names\n" ); 503 exit( EXIT_FAILURE ); 504 } // usage 505 506 static void parse_cmdline( int argc, char * argv[], const char *& filename ) { 440 507 opterr = 0; // (global) prevent getopt from printing error messages 441 508 442 509 bool Wsuppress = false, Werror = false; 443 510 int c; 444 while ( (c = getopt_long( argc, argv, "abBcCdefgGlLmnNpqrRstTvwW:yzZD:F:", long_opts, &long_index)) != -1 ) {511 while ( (c = getopt_long( argc, argv, optstring, long_opts, nullptr )) != -1 ) { 445 512 switch ( c ) { 446 case Ast: 447 case 'a': // dump AST 448 astp = true; 449 break; 450 case Bresolver: 451 case 'b': // print before resolver steps 452 bresolvep = true; 453 break; 454 case 'B': // print before box steps 455 bboxp = true; 456 break; 457 case CtorInitFix: 458 case 'c': // print after constructors and destructors are replaced 459 ctorinitp = true; 460 break; 461 case 'C': // print before code generation 462 bcodegenp = true; 463 break; 464 case DeclStats: 465 case 'd': 466 declstatsp = true; 467 break; 468 case Expr: 469 case 'e': // dump AST after expression analysis 470 exprp = true; 471 break; 472 case ExprAlt: 473 case 'f': // print alternatives for expressions 474 expraltp = true; 475 break; 476 case Grammar: 477 case 'g': // bison debugging info (grammar rules) 478 yydebug = true; 479 break; 480 case 'G': // dump AST after instantiate generics 481 genericsp = true; 482 break; 483 case LibCFA: 484 case 'l': // generate libcfa.c 513 case 'h': // help message 514 usage( argv ); // no return 515 break; 516 case 'l': // generate libcfa.c 485 517 libcfap = true; 486 518 break; 487 case Linemarks: 488 case 'L': // print lines marks 519 case 'L': // generate line marks 489 520 linemarks = true; 490 521 break; 491 case Nopreamble: 492 case 'n': // do not read preamble 522 case 'm': // do not replace main 523 nomainp = true; 524 break; 525 case 'N': // do not generate line marks 526 linemarks = false; 527 break; 528 case 'n': // do not read prelude 493 529 nopreludep = true; 494 530 break; 495 case Nolinemarks: 496 case 'N': // suppress line marks 497 linemarks = false; 498 break; 499 case Prototypes: 500 case 'p': // generate prototypes for preamble functions 501 noprotop = true; 502 break; 503 case PreludeDir: 504 PreludeDirector = optarg; 505 break; 506 case 'm': // don't replace the main 507 nomainp = true; 508 break; 509 case Parse: 510 case 'q': // dump parse tree 511 parsep = true; 512 break; 513 case Resolver: 514 case 'r': // print resolver steps 515 resolvep = true; 516 break; 517 case 'R': // dump resolv-proto instance 518 resolvprotop = true; 519 break; 520 case Stats: 521 Stats::parse_params(optarg); 522 break; 523 case Symbol: 524 case 's': // print symbol table events 525 symtabp = true; 526 break; 527 case Tree: 528 case 't': // build in tree 531 case 'p': // generate prototypes for prelude functions 532 genproto = true; 533 break; 534 case 'P': // print options 535 for ( int i = 0;; i += 1 ) { 536 if ( i == printoptsSize ) { 537 cout << "Unknown --print option " << optarg << endl; 538 goto Default; 539 } // if 540 if ( strcmp( optarg, printopts[i].name ) == 0 ) { 541 printopts[i].flag = printopts[i].val; 542 break; 543 } // if 544 } // for 545 break; 546 case PreludeDir: // prelude directory for debug/nodebug, hidden 547 PreludeDirector = optarg; 548 break; 549 case 'S': // enable profiling information, argument comma separated list of names 550 Stats::parse_params( optarg ); 551 break; 552 case 't': // build in tree 529 553 treep = true; 530 554 break; 531 case TupleExpansion: 532 case 'T': // print after tuple expansion 533 tuplep = true; 534 break; 535 case 'v': // dump AST after decl validation pass 536 validp = true; 537 break; 538 case 'w': 555 case 'w': // suppress all warnings, hidden 539 556 Wsuppress = true; 540 557 break; 541 case 'W':558 case 'W': // coordinate gcc -W with CFA, hidden 542 559 if ( strcmp( optarg, "all" ) == 0 ) { 543 560 SemanticWarning_EnableAll(); … … 556 573 } // if 557 574 break; 558 case 'y': // dump AST on error 559 errorp = true; 560 break; 561 case 'z': // dump as codegen rather than AST 562 codegenp = true; 563 break; 564 case 'Z': // prettyprint during codegen (i.e. print unmangled names, etc.) 565 prettycodegenp = true; 566 break; 567 case 'D': // ignore -Dxxx 568 break; 569 case 'F': // source file-name without suffix 575 case 'D': // ignore -Dxxx, forwarded by cpp, hidden 576 break; 577 case 'F': // source file-name without suffix, hidden 570 578 filename = optarg; 571 579 break; 572 case '?':580 case '?': // unknown option 573 581 if ( optopt ) { // short option ? 574 assertf( false, "Unknown option: -%c\n", (char)optopt );582 cout << "Unknown option -" << (char)optopt << endl; 575 583 } else { 576 assertf( false, "Unknown option: %s\n", argv[optind - 1] ); 577 } // if 578 #if defined(__GNUC__) && __GNUC__ >= 7 579 __attribute__((fallthrough)); 580 #endif 581 default: 582 abort(); 584 cout << "Unknown option " << argv[optind - 1] << endl; 585 } // if 586 goto Default; 587 case ':': // missing option 588 if ( optopt ) { // short option ? 589 cout << "Missing option for -" << (char)optopt << endl; 590 } else { 591 cout << "Missing option for " << argv[optind - 1] << endl; 592 } // if 593 goto Default; 594 Default: 595 default: 596 usage( argv ); // no return 583 597 } // switch 584 598 } // while … … 618 632 list< Declaration * > decls; 619 633 620 if ( noprotop) {634 if ( genproto ) { 621 635 filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), notPrelude ); 622 636 } else { … … 626 640 // depending on commandline options, either generate code or dump the AST 627 641 if ( codegenp ) { 628 CodeGen::generate( decls, out, ! noprotop, prettycodegenp );642 CodeGen::generate( decls, out, ! genproto, prettycodegenp ); 629 643 } else { 630 644 printAll( decls, out ); 631 } 645 } // if 632 646 deleteAll( translationUnit ); 633 647 } // dump
Note:
See TracChangeset
for help on using the changeset viewer.