- Timestamp:
- Jun 29, 2021, 5:35:19 PM (4 years ago)
- Branches:
- ADT, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- dcad80a
- Parents:
- 5a46e09 (diff), d02e547 (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:
-
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r5a46e09 r660665f 2415 2415 } 2416 2416 2417 virtual void visit( const DimensionExpr * old ) override final { 2418 // DimensionExpr gets desugared away in Validate. 2419 // As long as new-AST passes don't use it, this cheap-cheerful error 2420 // detection helps ensure that these occurrences have been compiled 2421 // away, as expected. To move the DimensionExpr boundary downstream 2422 // or move the new-AST translation boundary upstream, implement 2423 // DimensionExpr in the new AST and implement a conversion. 2424 (void) old; 2425 assert(false && "DimensionExpr should not be present at new-AST boundary"); 2426 } 2427 2417 2428 virtual void visit( const AsmExpr * old ) override final { 2418 2429 this->node = visitBaseExpr( old, -
src/AST/Decl.cpp
r5a46e09 r660665f 78 78 79 79 const char * TypeDecl::typeString() const { 80 static const char * kindNames[] = { "sized data type", "sized data type", "sized object type", "sized function type", "sized tuple type", "sized array length type" };80 static const char * kindNames[] = { "sized data type", "sized data type", "sized object type", "sized function type", "sized tuple type", "sized length value" }; 81 81 static_assert( sizeof(kindNames) / sizeof(kindNames[0]) == TypeDecl::NUMBER_OF_KINDS, "typeString: kindNames is out of sync." ); 82 82 assertf( kind < TypeDecl::NUMBER_OF_KINDS, "TypeDecl kind is out of bounds." ); -
src/AST/Decl.hpp
r5a46e09 r660665f 175 175 class TypeDecl final : public NamedTypeDecl { 176 176 public: 177 enum Kind { Dtype, DStype, Otype, Ftype, Ttype, ALtype, NUMBER_OF_KINDS };177 enum Kind { Dtype, DStype, Otype, Ftype, Ttype, Dimension, NUMBER_OF_KINDS }; 178 178 179 179 Kind kind; -
src/AST/Pass.impl.hpp
r5a46e09 r660665f 479 479 guard_symtab guard { *this }; 480 480 // implicit add __func__ identifier as specified in the C manual 6.4.2.2 481 static ast::ptr< ast::ObjectDecl > func{ new ast::ObjectDecl{ 481 static ast::ptr< ast::ObjectDecl > func{ new ast::ObjectDecl{ 482 482 CodeLocation{}, "__func__", 483 483 new ast::ArrayType{ … … 522 522 VISIT({ 523 523 guard_symtab guard { * this }; 524 maybe_accept( node, &StructDecl::params ); 525 maybe_accept( node, &StructDecl::members ); 524 maybe_accept( node, &StructDecl::params ); 525 maybe_accept( node, &StructDecl::members ); 526 maybe_accept( node, &StructDecl::attributes ); 526 527 }) 527 528 … … 543 544 VISIT({ 544 545 guard_symtab guard { * this }; 545 maybe_accept( node, &UnionDecl::params ); 546 maybe_accept( node, &UnionDecl::members ); 546 maybe_accept( node, &UnionDecl::params ); 547 maybe_accept( node, &UnionDecl::members ); 548 maybe_accept( node, &UnionDecl::attributes ); 547 549 }) 548 550 … … 562 564 VISIT( 563 565 // unlike structs, traits, and unions, enums inject their members into the global scope 564 maybe_accept( node, &EnumDecl::params ); 565 maybe_accept( node, &EnumDecl::members ); 566 maybe_accept( node, &EnumDecl::params ); 567 maybe_accept( node, &EnumDecl::members ); 568 maybe_accept( node, &EnumDecl::attributes ); 566 569 ) 567 570 … … 577 580 VISIT({ 578 581 guard_symtab guard { *this }; 579 maybe_accept( node, &TraitDecl::params ); 580 maybe_accept( node, &TraitDecl::members ); 582 maybe_accept( node, &TraitDecl::params ); 583 maybe_accept( node, &TraitDecl::members ); 584 maybe_accept( node, &TraitDecl::attributes ); 581 585 }) 582 586 -
src/CodeGen/CodeGenerator.cc
r5a46e09 r660665f 589 589 output << nameExpr->get_name(); 590 590 } // if 591 } 592 593 void CodeGenerator::postvisit( DimensionExpr * dimensionExpr ) { 594 extension( dimensionExpr ); 595 output << "/*non-type*/" << dimensionExpr->get_name(); 591 596 } 592 597 -
src/CodeGen/CodeGenerator.h
r5a46e09 r660665f 92 92 void postvisit( TupleIndexExpr * tupleExpr ); 93 93 void postvisit( TypeExpr *typeExpr ); 94 void postvisit( DimensionExpr *dimensionExpr ); 94 95 void postvisit( AsmExpr * ); 95 96 void postvisit( StmtExpr * ); -
src/Common/PassVisitor.h
r5a46e09 r660665f 167 167 virtual void visit( TypeExpr * typeExpr ) override final; 168 168 virtual void visit( const TypeExpr * typeExpr ) override final; 169 virtual void visit( DimensionExpr * dimensionExpr ) override final; 170 virtual void visit( const DimensionExpr * dimensionExpr ) override final; 169 171 virtual void visit( AsmExpr * asmExpr ) override final; 170 172 virtual void visit( const AsmExpr * asmExpr ) override final; … … 309 311 virtual Expression * mutate( CommaExpr * commaExpr ) override final; 310 312 virtual Expression * mutate( TypeExpr * typeExpr ) override final; 313 virtual Expression * mutate( DimensionExpr * dimensionExpr ) override final; 311 314 virtual Expression * mutate( AsmExpr * asmExpr ) override final; 312 315 virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) override final; … … 542 545 class WithIndexer { 543 546 protected: 544 WithIndexer( ) {}547 WithIndexer( bool trackIdentifiers = true ) : indexer(trackIdentifiers) {} 545 548 ~WithIndexer() {} 546 549 -
src/Common/PassVisitor.impl.h
r5a46e09 r660665f 636 636 maybeAccept_impl( node->parameters, *this ); 637 637 maybeAccept_impl( node->members , *this ); 638 maybeAccept_impl( node->attributes, *this ); 638 639 } 639 640 … … 656 657 maybeAccept_impl( node->parameters, *this ); 657 658 maybeAccept_impl( node->members , *this ); 659 maybeAccept_impl( node->attributes, *this ); 658 660 } 659 661 … … 676 678 maybeMutate_impl( node->parameters, *this ); 677 679 maybeMutate_impl( node->members , *this ); 680 maybeMutate_impl( node->attributes, *this ); 678 681 } 679 682 … … 697 700 maybeAccept_impl( node->parameters, *this ); 698 701 maybeAccept_impl( node->members , *this ); 702 maybeAccept_impl( node->attributes, *this ); 699 703 } 700 704 … … 714 718 maybeAccept_impl( node->parameters, *this ); 715 719 maybeAccept_impl( node->members , *this ); 720 maybeAccept_impl( node->attributes, *this ); 716 721 } 717 722 … … 732 737 maybeMutate_impl( node->parameters, *this ); 733 738 maybeMutate_impl( node->members , *this ); 739 maybeMutate_impl( node->attributes, *this ); 734 740 } 735 741 … … 750 756 maybeAccept_impl( node->parameters, *this ); 751 757 maybeAccept_impl( node->members , *this ); 758 maybeAccept_impl( node->attributes, *this ); 752 759 753 760 VISIT_END( node ); … … 763 770 maybeAccept_impl( node->parameters, *this ); 764 771 maybeAccept_impl( node->members , *this ); 772 maybeAccept_impl( node->attributes, *this ); 765 773 766 774 VISIT_END( node ); … … 776 784 maybeMutate_impl( node->parameters, *this ); 777 785 maybeMutate_impl( node->members , *this ); 786 maybeMutate_impl( node->attributes, *this ); 778 787 779 788 MUTATE_END( Declaration, node ); … … 790 799 maybeAccept_impl( node->parameters, *this ); 791 800 maybeAccept_impl( node->members , *this ); 801 maybeAccept_impl( node->attributes, *this ); 792 802 } 793 803 … … 805 815 maybeAccept_impl( node->parameters, *this ); 806 816 maybeAccept_impl( node->members , *this ); 817 maybeAccept_impl( node->attributes, *this ); 807 818 } 808 819 … … 820 831 maybeMutate_impl( node->parameters, *this ); 821 832 maybeMutate_impl( node->members , *this ); 833 maybeMutate_impl( node->attributes, *this ); 822 834 } 823 835 … … 2507 2519 2508 2520 //-------------------------------------------------------------------------- 2521 // DimensionExpr 2522 template< typename pass_type > 2523 void PassVisitor< pass_type >::visit( DimensionExpr * node ) { 2524 VISIT_START( node ); 2525 2526 indexerScopedAccept( node->result, *this ); 2527 2528 VISIT_END( node ); 2529 } 2530 2531 template< typename pass_type > 2532 void PassVisitor< pass_type >::visit( const DimensionExpr * node ) { 2533 VISIT_START( node ); 2534 2535 indexerScopedAccept( node->result, *this ); 2536 2537 VISIT_END( node ); 2538 } 2539 2540 template< typename pass_type > 2541 Expression * PassVisitor< pass_type >::mutate( DimensionExpr * node ) { 2542 MUTATE_START( node ); 2543 2544 indexerScopedMutate( node->env , *this ); 2545 indexerScopedMutate( node->result, *this ); 2546 2547 MUTATE_END( Expression, node ); 2548 } 2549 2550 //-------------------------------------------------------------------------- 2509 2551 // AsmExpr 2510 2552 template< typename pass_type > … … 3145 3187 3146 3188 maybeAccept_impl( node->forall, *this ); 3147 // xxx - should PointerType visit/mutate dimension?3189 maybeAccept_impl( node->dimension, *this ); 3148 3190 maybeAccept_impl( node->base, *this ); 3149 3191 … … 3156 3198 3157 3199 maybeAccept_impl( node->forall, *this ); 3158 // xxx - should PointerType visit/mutate dimension?3200 maybeAccept_impl( node->dimension, *this ); 3159 3201 maybeAccept_impl( node->base, *this ); 3160 3202 … … 3167 3209 3168 3210 maybeMutate_impl( node->forall, *this ); 3169 // xxx - should PointerType visit/mutate dimension?3211 maybeMutate_impl( node->dimension, *this ); 3170 3212 maybeMutate_impl( node->base, *this ); 3171 3213 … … 3856 3898 3857 3899 //-------------------------------------------------------------------------- 3858 // Attribute3900 // Constant 3859 3901 template< typename pass_type > 3860 3902 void PassVisitor< pass_type >::visit( Constant * node ) { -
src/InitTweak/InitTweak.cc
r5a46e09 r660665f 10 10 // Created On : Fri May 13 11:26:36 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Dec 13 23:15:52 201913 // Update Count : 812 // Last Modified On : Wed Jun 16 20:57:22 2021 13 // Update Count : 18 14 14 // 15 15 … … 1217 1217 void addDataSectonAttribute( ObjectDecl * objDecl ) { 1218 1218 objDecl->attributes.push_back(new Attribute("section", { 1219 new ConstantExpr( Constant::from_string(".data#") ), 1220 })); 1219 new ConstantExpr( Constant::from_string(".data" 1220 #if defined( __x86_64 ) || defined( __i386 ) // assembler comment to prevent assembler warning message 1221 "#" 1222 #else // defined( __ARM_ARCH ) 1223 "//" 1224 #endif 1225 ))})); 1221 1226 } 1222 1227 1223 1228 void addDataSectionAttribute( ast::ObjectDecl * objDecl ) { 1224 1229 objDecl->attributes.push_back(new ast::Attribute("section", { 1225 ast::ConstantExpr::from_string(objDecl->location, ".data#"), 1226 })); 1230 ast::ConstantExpr::from_string(objDecl->location, ".data" 1231 #if defined( __x86_64 ) || defined( __i386 ) // assembler comment to prevent assembler warning message 1232 "#" 1233 #else // defined( __ARM_ARCH ) 1234 "//" 1235 #endif 1236 )})); 1227 1237 } 1228 1238 -
src/Parser/DeclarationNode.cc
r5a46e09 r660665f 1076 1076 if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) { 1077 1077 // otype is internally converted to dtype + otype parameters 1078 static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::D Stype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype, TypeDecl::Dtype};1078 static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype, TypeDecl::Dimension }; 1079 1079 static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." ); 1080 1080 assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." ); 1081 TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == TypeDecl::Otype || variable.tyClass == TypeDecl:: ALtype, variable.initializer ? variable.initializer->buildType() : nullptr );1081 TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == TypeDecl::Otype || variable.tyClass == TypeDecl::DStype, variable.initializer ? variable.initializer->buildType() : nullptr ); 1082 1082 buildList( variable.assertions, ret->get_assertions() ); 1083 1083 return ret; -
src/Parser/ExpressionNode.cc
r5a46e09 r660665f 509 509 } // build_varref 510 510 511 DimensionExpr * build_dimensionref( const string * name ) { 512 DimensionExpr * expr = new DimensionExpr( *name ); 513 delete name; 514 return expr; 515 } // build_varref 511 516 // TODO: get rid of this and OperKinds and reuse code from OperatorTable 512 517 static const char * OperName[] = { // must harmonize with OperKinds -
src/Parser/ParseNode.h
r5a46e09 r660665f 183 183 184 184 NameExpr * build_varref( const std::string * name ); 185 DimensionExpr * build_dimensionref( const std::string * name ); 185 186 186 187 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ); -
src/Parser/TypedefTable.cc
r5a46e09 r660665f 10 10 // Created On : Sat May 16 15:20:13 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 15 20:56:47202113 // Update Count : 26 012 // Last Modified On : Wed May 19 08:30:14 2021 13 // Update Count : 262 14 14 // 15 15 … … 31 31 switch ( kind ) { 32 32 case IDENTIFIER: return "identifier"; 33 case TYPEDIMname: return "typedim"; 33 34 case TYPEDEFname: return "typedef"; 34 35 case TYPEGENname: return "typegen"; -
src/Parser/lex.ll
r5a46e09 r660665f 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Thu Apr 1 13:22:31202113 * Update Count : 75 412 * Last Modified On : Sun Jun 20 18:41:09 2021 13 * Update Count : 759 14 14 */ 15 15 … … 117 117 hex_constant {hex_prefix}{hex_digits}{integer_suffix_opt} 118 118 119 // GCC: D (double) and iI (imaginary) suffixes, and DL (long double)119 // GCC: floating D (double), imaginary iI, and decimal floating DF, DD, DL 120 120 exponent "_"?[eE]"_"?[+-]?{decimal_digits} 121 121 floating_size 16|32|32x|64|64x|80|128|128x 122 122 floating_length ([fFdDlLwWqQ]|[fF]{floating_size}) 123 123 floating_suffix ({floating_length}?[iI]?)|([iI]{floating_length}) 124 floating_suffix_opt ("_"?({floating_suffix}|"DL"))? 124 decimal_floating_suffix [dD][fFdDlL] 125 floating_suffix_opt ("_"?({floating_suffix}|{decimal_floating_suffix}))? 125 126 decimal_digits ({decimal})|({decimal}({decimal}|"_")*{decimal}) 126 127 floating_decimal {decimal_digits}"."{exponent}?{floating_suffix_opt} … … 234 235 continue { KEYWORD_RETURN(CONTINUE); } 235 236 coroutine { KEYWORD_RETURN(COROUTINE); } // CFA 237 _Decimal32 { KEYWORD_RETURN(DECIMAL32); } // GCC 238 _Decimal64 { KEYWORD_RETURN(DECIMAL64); } // GCC 239 _Decimal128 { KEYWORD_RETURN(DECIMAL128); } // GCC 236 240 default { KEYWORD_RETURN(DEFAULT); } 237 241 disable { KEYWORD_RETURN(DISABLE); } // CFA -
src/Parser/parser.yy
r5a46e09 r660665f 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Apr 26 18:41:54202113 // Update Count : 499012 // Last Modified On : Tue Jun 29 09:12:47 2021 13 // Update Count : 5027 14 14 // 15 15 … … 26 26 // The root language for this grammar is ANSI99/11 C. All of ANSI99/11 is parsed, except for: 27 27 // 28 // 1. designation with '=' (use ':' instead) 29 // 30 // Most of the syntactic extensions from ANSI90 to ANSI11 C are marked with the comment "C99/C11". This grammar also has 31 // two levels of extensions. The first extensions cover most of the GCC C extensions, except for: 32 // 33 // 1. designation with and without '=' (use ':' instead) 34 35 // 36 // All of the syntactic extensions for GCC C are marked with the comment "GCC". The second extensions are for Cforall 37 // (CFA), which fixes several of C's outstanding problems and extends C with many modern language concepts. All of the 38 // syntactic extensions for CFA C are marked with the comment "CFA". As noted above, there is one unreconcileable 39 // parsing problem between C99 and CFA with respect to designators; this is discussed in detail before the "designation" 40 // grammar rule. 28 // designation with '=' (use ':' instead) 29 // 30 // This incompatibility is discussed in detail before the "designation" grammar rule. Most of the syntactic extensions 31 // from ANSI90 to ANSI11 C are marked with the comment "C99/C11". 32 33 // This grammar also has two levels of extensions. The first extensions cover most of the GCC C extensions All of the 34 // syntactic extensions for GCC C are marked with the comment "GCC". The second extensions are for Cforall (CFA), which 35 // fixes several of C's outstanding problems and extends C with many modern language concepts. All of the syntactic 36 // extensions for CFA C are marked with the comment "CFA". 41 37 42 38 %{ … … 269 265 %token INT128 UINT128 uuFLOAT80 uuFLOAT128 // GCC 270 266 %token uFLOAT16 uFLOAT32 uFLOAT32X uFLOAT64 uFLOAT64X uFLOAT128 // GCC 267 %token DECIMAL32 DECIMAL64 DECIMAL128 // GCC 271 268 %token ZERO_T ONE_T // CFA 272 269 %token SIZEOF TYPEOF VALIST AUTO_TYPE // GCC … … 287 284 288 285 // names and constants: lexer differentiates between identifier and typedef names 289 %token<tok> IDENTIFIER QUOTED_IDENTIFIER TYPED EFname TYPEGENname286 %token<tok> IDENTIFIER QUOTED_IDENTIFIER TYPEDIMname TYPEDEFname TYPEGENname 290 287 %token<tok> TIMEOUT WOR CATCH RECOVER CATCHRESUME FIXUP FINALLY // CFA 291 288 %token<tok> INTEGERconstant CHARACTERconstant STRINGliteral … … 586 583 | quasi_keyword 587 584 { $$ = new ExpressionNode( build_varref( $1 ) ); } 585 | TYPEDIMname // CFA, generic length argument 586 // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); } 587 // { $$ = new ExpressionNode( build_varref( $1 ) ); } 588 { $$ = new ExpressionNode( build_dimensionref( $1 ) ); } 588 589 | tuple 589 590 | '(' comma_expression ')' … … 630 631 postfix_expression: 631 632 primary_expression 632 | postfix_expression '[' assignment_expression ',' comma_expression ']' 633 // { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_binary_val( OperKinds::Index, $3, $5 ) ) ) ); } 634 { SemanticError( yylloc, "New array subscript is currently unimplemented." ); $$ = nullptr; } 633 | postfix_expression '[' assignment_expression ',' tuple_expression_list ']' 634 // Historic, transitional: Disallow commas in subscripts. 635 // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts. 636 // { SemanticError( yylloc, "New array subscript is currently unimplemented." ); $$ = nullptr; } 637 // Current: Commas in subscripts make tuples. 638 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); } 635 639 | postfix_expression '[' assignment_expression ']' 636 640 // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a … … 1887 1891 | uFLOAT128 1888 1892 { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat128 ); } 1893 | DECIMAL32 1894 { SemanticError( yylloc, "_Decimal32 is currently unimplemented." ); $$ = nullptr; } 1895 | DECIMAL64 1896 { SemanticError( yylloc, "_Decimal64 is currently unimplemented." ); $$ = nullptr; } 1897 | DECIMAL128 1898 { SemanticError( yylloc, "_Decimal128 is currently unimplemented." ); $$ = nullptr; } 1889 1899 | COMPLEX // C99 1890 1900 { $$ = DeclarationNode::newComplexType( DeclarationNode::Complex ); } … … 1909 1919 // empty 1910 1920 { $$ = nullptr; } 1911 | vtable ;1921 | vtable 1912 1922 ; 1913 1923 … … 2535 2545 | '[' identifier_or_type_name ']' 2536 2546 { 2537 typedefTable.addToScope( *$2, TYPED EFname, "9" );2538 $$ = DeclarationNode::newTypeParam( TypeDecl:: ALtype, $2 );2547 typedefTable.addToScope( *$2, TYPEDIMname, "9" ); 2548 $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 ); 2539 2549 } 2540 2550 // | type_specifier identifier_parameter_declarator … … 2550 2560 | '*' 2551 2561 { $$ = TypeDecl::DStype; } // dtype + sized 2562 // | '(' '*' ')' 2563 // { $$ = TypeDecl::Ftype; } 2552 2564 | ELLIPSIS 2553 2565 { $$ = TypeDecl::Ttype; } … … 2590 2602 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); } 2591 2603 | assignment_expression 2592 { SemanticError( yylloc, toString("Expression generic parameters are currently unimplemented: ", $1->build()) ); $$ = nullptr; }2593 2604 | type_list ',' type 2594 2605 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); } 2595 2606 | type_list ',' assignment_expression 2596 { SemanticError( yylloc, toString("Expression generic parameters are currently unimplemented: ", $3->build()) ); $$ = nullptr; } 2597 // { $$ = (ExpressionNode *)( $1->set_last( $3 )); } 2607 { $$ = (ExpressionNode *)( $1->set_last( $3 )); } 2598 2608 ; 2599 2609 -
src/SymTab/Indexer.cc
r5a46e09 r660665f 74 74 } 75 75 76 Indexer::Indexer( )76 Indexer::Indexer( bool trackIdentifiers ) 77 77 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 78 prevScope(), scope( 0 ), repScope( 0 ) { ++* stats().count; }78 prevScope(), scope( 0 ), repScope( 0 ), trackIdentifiers( trackIdentifiers ) { ++* stats().count; } 79 79 80 80 Indexer::~Indexer() { … … 110 110 111 111 void Indexer::lookupId( const std::string & id, std::list< IdData > &out ) const { 112 assert( trackIdentifiers ); 113 112 114 ++* stats().lookup_calls; 113 115 if ( ! idTable ) return; … … 434 436 const Declaration * deleteStmt ) { 435 437 ++* stats().add_calls; 438 if ( ! trackIdentifiers ) return; 436 439 const std::string &name = decl->name; 437 440 if ( name == "" ) return; -
src/SymTab/Indexer.h
r5a46e09 r660665f 31 31 class Indexer : public std::enable_shared_from_this<SymTab::Indexer> { 32 32 public: 33 explicit Indexer( );33 explicit Indexer( bool trackIdentifiers = true ); 34 34 virtual ~Indexer(); 35 35 … … 180 180 /// returns true if there exists a declaration with C linkage and the given name with a different mangled name 181 181 bool hasIncompatibleCDecl( const std::string & id, const std::string & mangleName ) const; 182 183 bool trackIdentifiers; 182 184 }; 183 185 } // namespace SymTab -
src/SymTab/Validate.cc
r5a46e09 r660665f 105 105 106 106 struct FixQualifiedTypes final : public WithIndexer { 107 FixQualifiedTypes() : WithIndexer(false) {} 107 108 Type * postmutate( QualifiedType * ); 108 109 }; … … 174 175 }; 175 176 177 /// Does early resolution on the expressions that give enumeration constants their values 178 struct ResolveEnumInitializers final : public WithIndexer, public WithGuards, public WithVisitorRef<ResolveEnumInitializers>, public WithShortCircuiting { 179 ResolveEnumInitializers( const Indexer * indexer ); 180 void postvisit( EnumDecl * enumDecl ); 181 182 private: 183 const Indexer * local_indexer; 184 185 }; 186 176 187 /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID. 177 188 struct ForallPointerDecay_old final { … … 260 271 void previsit( StructInstType * inst ); 261 272 void previsit( UnionInstType * inst ); 273 }; 274 275 /// desugar declarations and uses of dimension paramaters like [N], 276 /// from type-system managed values, to tunnneling via ordinary types, 277 /// as char[-] in and sizeof(-) out 278 struct TranslateDimensionGenericParameters : public WithIndexer, public WithGuards { 279 static void translateDimensions( std::list< Declaration * > &translationUnit ); 280 TranslateDimensionGenericParameters(); 281 282 bool nextVisitedNodeIsChildOfSUIT = false; // SUIT = Struct or Union -Inst Type 283 bool visitingChildOfSUIT = false; 284 void changeState_ChildOfSUIT( bool newVal ); 285 void premutate( StructInstType * sit ); 286 void premutate( UnionInstType * uit ); 287 void premutate( BaseSyntaxNode * node ); 288 289 TypeDecl * postmutate( TypeDecl * td ); 290 Expression * postmutate( DimensionExpr * de ); 291 Expression * postmutate( Expression * e ); 262 292 }; 263 293 … … 307 337 PassVisitor<EnumAndPointerDecay_old> epc; 308 338 PassVisitor<LinkReferenceToTypes_old> lrt( nullptr ); 339 PassVisitor<ResolveEnumInitializers> rei( nullptr ); 309 340 PassVisitor<ForallPointerDecay_old> fpd; 310 341 PassVisitor<CompoundLiteral> compoundliteral; … … 326 357 Stats::Heap::newPass("validate-B"); 327 358 Stats::Time::BlockGuard guard("validate-B"); 328 Stats::Time::TimeBlock("Link Reference To Types", [&]() { 329 acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions 330 }); 331 Stats::Time::TimeBlock("Fix Qualified Types", [&]() { 332 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes_old, because aggregate members are accessed 333 }); 334 Stats::Time::TimeBlock("Hoist Structs", [&]() { 335 HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order 336 }); 337 Stats::Time::TimeBlock("Eliminate Typedefs", [&]() { 338 EliminateTypedef::eliminateTypedef( translationUnit ); // 339 }); 359 acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions 360 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes_old, because aggregate members are accessed 361 HoistStruct::hoistStruct( translationUnit ); 362 EliminateTypedef::eliminateTypedef( translationUnit ); 340 363 } 341 364 { 342 365 Stats::Heap::newPass("validate-C"); 343 366 Stats::Time::BlockGuard guard("validate-C"); 344 acceptAll( translationUnit, genericParams ); // check as early as possible - can't happen before LinkReferenceToTypes_old 345 ReturnChecker::checkFunctionReturns( translationUnit ); 346 InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen 367 Stats::Time::TimeBlock("Validate Generic Parameters", [&]() { 368 acceptAll( translationUnit, genericParams ); // check as early as possible - can't happen before LinkReferenceToTypes_old; observed failing when attempted before eliminateTypedef 369 }); 370 Stats::Time::TimeBlock("Translate Dimensions", [&]() { 371 TranslateDimensionGenericParameters::translateDimensions( translationUnit ); 372 }); 373 Stats::Time::TimeBlock("Resolve Enum Initializers", [&]() { 374 acceptAll( translationUnit, rei ); // must happen after translateDimensions because rei needs identifier lookup, which needs name mangling 375 }); 376 Stats::Time::TimeBlock("Check Function Returns", [&]() { 377 ReturnChecker::checkFunctionReturns( translationUnit ); 378 }); 379 Stats::Time::TimeBlock("Fix Return Statements", [&]() { 380 InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen 381 }); 347 382 } 348 383 { … … 644 679 } 645 680 646 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) {681 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) : WithIndexer( false ) { 647 682 if ( other_indexer ) { 648 683 local_indexer = other_indexer; … … 664 699 } 665 700 666 void checkGenericParameters( ReferenceToType * inst ) {667 for ( Expression * param : inst->parameters ) {668 if ( ! dynamic_cast< TypeExpr * >( param ) ) {669 SemanticError( inst, "Expression parameters for generic types are currently unsupported: " );670 }671 }672 }673 674 701 void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) { 675 702 const StructDecl * st = local_indexer->lookupStruct( structInst->name ); … … 682 709 forwardStructs[ structInst->name ].push_back( structInst ); 683 710 } // if 684 checkGenericParameters( structInst );685 711 } 686 712 … … 695 721 forwardUnions[ unionInst->name ].push_back( unionInst ); 696 722 } // if 697 checkGenericParameters( unionInst );698 723 } 699 724 … … 807 832 forwardEnums.erase( fwds ); 808 833 } // if 809 810 for ( Declaration * member : enumDecl->members ) {811 ObjectDecl * field = strict_dynamic_cast<ObjectDecl *>( member );812 if ( field->init ) {813 // need to resolve enumerator initializers early so that other passes that determine if an expression is constexpr have the appropriate information.814 SingleInit * init = strict_dynamic_cast<SingleInit *>( field->init );815 ResolvExpr::findSingleExpression( init->value, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), indexer );816 }817 }818 834 } // if 819 835 } … … 878 894 typeInst->set_isFtype( typeDecl->kind == TypeDecl::Ftype ); 879 895 } // if 896 } // if 897 } 898 899 ResolveEnumInitializers::ResolveEnumInitializers( const Indexer * other_indexer ) : WithIndexer( true ) { 900 if ( other_indexer ) { 901 local_indexer = other_indexer; 902 } else { 903 local_indexer = &indexer; 904 } // if 905 } 906 907 void ResolveEnumInitializers::postvisit( EnumDecl * enumDecl ) { 908 if ( enumDecl->body ) { 909 for ( Declaration * member : enumDecl->members ) { 910 ObjectDecl * field = strict_dynamic_cast<ObjectDecl *>( member ); 911 if ( field->init ) { 912 // need to resolve enumerator initializers early so that other passes that determine if an expression is constexpr have the appropriate information. 913 SingleInit * init = strict_dynamic_cast<SingleInit *>( field->init ); 914 ResolvExpr::findSingleExpression( init->value, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), indexer ); 915 } 916 } 880 917 } // if 881 918 } … … 1152 1189 GuardScope( typedeclNames ); 1153 1190 mutateAll( aggr->parameters, * visitor ); 1191 mutateAll( aggr->attributes, * visitor ); 1154 1192 1155 1193 // unroll mutateAll for aggr->members so that implicit typedefs for nested types are added to the aggregate body. … … 1220 1258 } 1221 1259 } 1260 } 1261 1262 // Test for special name on a generic parameter. Special treatment for the 1263 // special name is a bootstrapping hack. In most cases, the worlds of T's 1264 // and of N's don't overlap (normal treamtemt). The foundations in 1265 // array.hfa use tagging for both types and dimensions. Tagging treats 1266 // its subject parameter even more opaquely than T&, which assumes it is 1267 // possible to have a pointer/reference to such an object. Tagging only 1268 // seeks to identify the type-system resident at compile time. Both N's 1269 // and T's can make tags. The tag definition uses the special name, which 1270 // is treated as "an N or a T." This feature is not inteded to be used 1271 // outside of the definition and immediate uses of a tag. 1272 static inline bool isReservedTysysIdOnlyName( const std::string & name ) { 1273 // name's prefix was __CFA_tysys_id_only, before it got wrapped in __..._generic 1274 int foundAt = name.find("__CFA_tysys_id_only"); 1275 if (foundAt == 0) return true; 1276 if (foundAt == 2 && name[0] == '_' && name[1] == '_') return true; 1277 return false; 1222 1278 } 1223 1279 … … 1238 1294 TypeSubstitution sub; 1239 1295 auto paramIter = params->begin(); 1240 for ( size_t i = 0; paramIter != params->end(); ++paramIter, ++i ) { 1241 if ( i < args.size() ) { 1242 TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( * std::next( args.begin(), i ) ); 1243 sub.add( (* paramIter)->get_name(), expr->get_type()->clone() ); 1244 } else if ( i == args.size() ) { 1296 auto argIter = args.begin(); 1297 for ( ; paramIter != params->end(); ++paramIter, ++argIter ) { 1298 if ( argIter != args.end() ) { 1299 TypeExpr * expr = dynamic_cast< TypeExpr * >( * argIter ); 1300 if ( expr ) { 1301 sub.add( (* paramIter)->get_name(), expr->get_type()->clone() ); 1302 } 1303 } else { 1245 1304 Type * defaultType = (* paramIter)->get_init(); 1246 1305 if ( defaultType ) { 1247 1306 args.push_back( new TypeExpr( defaultType->clone() ) ); 1248 1307 sub.add( (* paramIter)->get_name(), defaultType->clone() ); 1308 argIter = std::prev(args.end()); 1309 } else { 1310 SemanticError( inst, "Too few type arguments in generic type " ); 1249 1311 } 1250 1312 } 1313 assert( argIter != args.end() ); 1314 bool typeParamDeclared = (*paramIter)->kind != TypeDecl::Kind::Dimension; 1315 bool typeArgGiven; 1316 if ( isReservedTysysIdOnlyName( (*paramIter)->name ) ) { 1317 // coerce a match when declaration is reserved name, which means "either" 1318 typeArgGiven = typeParamDeclared; 1319 } else { 1320 typeArgGiven = dynamic_cast< TypeExpr * >( * argIter ); 1321 } 1322 if ( ! typeParamDeclared && typeArgGiven ) SemanticError( inst, "Type argument given for value parameter: " ); 1323 if ( typeParamDeclared && ! typeArgGiven ) SemanticError( inst, "Expression argument given for type parameter: " ); 1251 1324 } 1252 1325 1253 1326 sub.apply( inst ); 1254 if ( args.size() < params->size() ) SemanticError( inst, "Too few type arguments in generic type " );1255 1327 if ( args.size() > params->size() ) SemanticError( inst, "Too many type arguments in generic type " ); 1256 1328 } … … 1263 1335 void ValidateGenericParameters::previsit( UnionInstType * inst ) { 1264 1336 validateGeneric( inst ); 1337 } 1338 1339 void TranslateDimensionGenericParameters::translateDimensions( std::list< Declaration * > &translationUnit ) { 1340 PassVisitor<TranslateDimensionGenericParameters> translator; 1341 mutateAll( translationUnit, translator ); 1342 } 1343 1344 TranslateDimensionGenericParameters::TranslateDimensionGenericParameters() : WithIndexer( false ) {} 1345 1346 // Declaration of type variable: forall( [N] ) -> forall( N & | sized( N ) ) 1347 TypeDecl * TranslateDimensionGenericParameters::postmutate( TypeDecl * td ) { 1348 if ( td->kind == TypeDecl::Dimension ) { 1349 td->kind = TypeDecl::Dtype; 1350 if ( ! isReservedTysysIdOnlyName( td->name ) ) { 1351 td->sized = true; 1352 } 1353 } 1354 return td; 1355 } 1356 1357 // Situational awareness: 1358 // array( float, [[currentExpr]] ) has visitingChildOfSUIT == true 1359 // array( float, [[currentExpr]] - 1 ) has visitingChildOfSUIT == false 1360 // size_t x = [[currentExpr]] has visitingChildOfSUIT == false 1361 void TranslateDimensionGenericParameters::changeState_ChildOfSUIT( bool newVal ) { 1362 GuardValue( nextVisitedNodeIsChildOfSUIT ); 1363 GuardValue( visitingChildOfSUIT ); 1364 visitingChildOfSUIT = nextVisitedNodeIsChildOfSUIT; 1365 nextVisitedNodeIsChildOfSUIT = newVal; 1366 } 1367 void TranslateDimensionGenericParameters::premutate( StructInstType * sit ) { 1368 (void) sit; 1369 changeState_ChildOfSUIT(true); 1370 } 1371 void TranslateDimensionGenericParameters::premutate( UnionInstType * uit ) { 1372 (void) uit; 1373 changeState_ChildOfSUIT(true); 1374 } 1375 void TranslateDimensionGenericParameters::premutate( BaseSyntaxNode * node ) { 1376 (void) node; 1377 changeState_ChildOfSUIT(false); 1378 } 1379 1380 // Passing values as dimension arguments: array( float, 7 ) -> array( float, char[ 7 ] ) 1381 // Consuming dimension parameters: size_t x = N - 1 ; -> size_t x = sizeof(N) - 1 ; 1382 // Intertwined reality: array( float, N ) -> array( float, N ) 1383 // array( float, N - 1 ) -> array( float, char[ sizeof(N) - 1 ] ) 1384 // Intertwined case 1 is not just an optimization. 1385 // Avoiding char[sizeof(-)] is necessary to enable the call of f to bind the value of N, in: 1386 // forall([N]) void f( array(float, N) & ); 1387 // array(float, 7) a; 1388 // f(a); 1389 1390 Expression * TranslateDimensionGenericParameters::postmutate( DimensionExpr * de ) { 1391 // Expression de is an occurrence of N in LHS of above examples. 1392 // Look up the name that de references. 1393 // If we are in a struct body, then this reference can be to an entry of the stuct's forall list. 1394 // Whether or not we are in a struct body, this reference can be to an entry of a containing function's forall list. 1395 // If we are in a struct body, then the stuct's forall declarations are innermost (functions don't occur in structs). 1396 // Thus, a potential struct's declaration is highest priority. 1397 // A struct's forall declarations are already renamed with _generic_ suffix. Try that name variant first. 1398 1399 std::string useName = "__" + de->name + "_generic_"; 1400 TypeDecl * namedParamDecl = const_cast<TypeDecl *>( strict_dynamic_cast<const TypeDecl *, nullptr >( indexer.lookupType( useName ) ) ); 1401 1402 if ( ! namedParamDecl ) { 1403 useName = de->name; 1404 namedParamDecl = const_cast<TypeDecl *>( strict_dynamic_cast<const TypeDecl *, nullptr >( indexer.lookupType( useName ) ) ); 1405 } 1406 1407 // Expect to find it always. A misspelled name would have been parsed as an identifier. 1408 assert( namedParamDecl && "Type-system-managed value name not found in symbol table" ); 1409 1410 delete de; 1411 1412 TypeInstType * refToDecl = new TypeInstType( 0, useName, namedParamDecl ); 1413 1414 if ( visitingChildOfSUIT ) { 1415 // As in postmutate( Expression * ), topmost expression needs a TypeExpr wrapper 1416 // But avoid ArrayType-Sizeof 1417 return new TypeExpr( refToDecl ); 1418 } else { 1419 // the N occurrence is being used directly as a runtime value, 1420 // if we are in a type instantiation, then the N is within a bigger value computation 1421 return new SizeofExpr( refToDecl ); 1422 } 1423 } 1424 1425 Expression * TranslateDimensionGenericParameters::postmutate( Expression * e ) { 1426 if ( visitingChildOfSUIT ) { 1427 // e is an expression used as an argument to instantiate a type 1428 if (! dynamic_cast< TypeExpr * >( e ) ) { 1429 // e is a value expression 1430 // but not a DimensionExpr, which has a distinct postmutate 1431 Type * typeExprContent = new ArrayType( 0, new BasicType( 0, BasicType::Char ), e, true, false ); 1432 TypeExpr * result = new TypeExpr( typeExprContent ); 1433 return result; 1434 } 1435 } 1436 return e; 1265 1437 } 1266 1438 -
src/SynTree/Declaration.h
r5a46e09 r660665f 201 201 typedef NamedTypeDecl Parent; 202 202 public: 203 enum Kind { Dtype, DStype, Otype, Ftype, Ttype, ALtype, NUMBER_OF_KINDS };203 enum Kind { Dtype, DStype, Otype, Ftype, Ttype, Dimension, NUMBER_OF_KINDS }; 204 204 205 205 Kind kind; -
src/SynTree/Expression.h
r5a46e09 r660665f 587 587 }; 588 588 589 /// DimensionExpr represents a type-system provided value used in an expression ( forrall([N]) ... N + 1 ) 590 class DimensionExpr : public Expression { 591 public: 592 std::string name; 593 594 DimensionExpr( std::string name ); 595 DimensionExpr( const DimensionExpr & other ); 596 virtual ~DimensionExpr(); 597 598 const std::string & get_name() const { return name; } 599 void set_name( std::string newValue ) { name = newValue; } 600 601 virtual DimensionExpr * clone() const override { return new DimensionExpr( * this ); } 602 virtual void accept( Visitor & v ) override { v.visit( this ); } 603 virtual void accept( Visitor & v ) const override { v.visit( this ); } 604 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 605 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 606 }; 607 589 608 /// AsmExpr represents a GCC 'asm constraint operand' used in an asm statement: [output] "=f" (result) 590 609 class AsmExpr : public Expression { -
src/SynTree/Mutator.h
r5a46e09 r660665f 80 80 virtual Expression * mutate( CommaExpr * commaExpr ) = 0; 81 81 virtual Expression * mutate( TypeExpr * typeExpr ) = 0; 82 virtual Expression * mutate( DimensionExpr * dimensionExpr ) = 0; 82 83 virtual Expression * mutate( AsmExpr * asmExpr ) = 0; 83 84 virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) = 0; -
src/SynTree/SynTree.h
r5a46e09 r660665f 85 85 class CommaExpr; 86 86 class TypeExpr; 87 class DimensionExpr; 87 88 class AsmExpr; 88 89 class ImplicitCopyCtorExpr; -
src/SynTree/TypeDecl.cc
r5a46e09 r660665f 33 33 34 34 const char * TypeDecl::typeString() const { 35 static const char * kindNames[] = { "sized data type", "sized data type", "sized object type", "sized function type", "sized tuple type", "sized array length type" };35 static const char * kindNames[] = { "sized data type", "sized data type", "sized object type", "sized function type", "sized tuple type", "sized length value" }; 36 36 static_assert( sizeof(kindNames) / sizeof(kindNames[0]) == TypeDecl::NUMBER_OF_KINDS, "typeString: kindNames is out of sync." ); 37 37 assertf( kind < TypeDecl::NUMBER_OF_KINDS, "TypeDecl kind is out of bounds." ); -
src/SynTree/TypeExpr.cc
r5a46e09 r660665f 35 35 } 36 36 37 DimensionExpr::DimensionExpr( std::string name ) : Expression(), name(name) { 38 assertf(name != "0", "Zero is not a valid name"); 39 assertf(name != "1", "One is not a valid name"); 40 } 41 42 DimensionExpr::DimensionExpr( const DimensionExpr & other ) : Expression( other ), name( other.name ) { 43 } 44 45 DimensionExpr::~DimensionExpr() {} 46 47 void DimensionExpr::print( std::ostream & os, Indenter indent ) const { 48 os << "Type-Sys Value: " << get_name(); 49 Expression::print( os, indent ); 50 } 37 51 // Local Variables: // 38 52 // tab-width: 4 // -
src/SynTree/Visitor.h
r5a46e09 r660665f 135 135 virtual void visit( TypeExpr * node ) { visit( const_cast<const TypeExpr *>(node) ); } 136 136 virtual void visit( const TypeExpr * typeExpr ) = 0; 137 virtual void visit( DimensionExpr * node ) { visit( const_cast<const DimensionExpr *>(node) ); } 138 virtual void visit( const DimensionExpr * typeExpr ) = 0; 137 139 virtual void visit( AsmExpr * node ) { visit( const_cast<const AsmExpr *>(node) ); } 138 140 virtual void visit( const AsmExpr * asmExpr ) = 0;
Note:
See TracChangeset
for help on using the changeset viewer.