Changeset 1b41219
- Timestamp:
- Oct 17, 2023, 8:50:05 AM (14 months ago)
- Branches:
- master
- Children:
- 37ceccb
- Parents:
- 2bf46a5 (diff), d85141f (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. - Files:
-
- 5 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/enum.tex
r2bf46a5 r1b41219 73 73 74 74 75 76 %%77 %% Submission ID.78 %% Use this when submitting an article to a sponsored event. You'll79 %% receive a unique submission ID from the organizers80 %% of the event, and this ID should be used as the parameter to this command.81 %%\acmSubmissionID{123-A56-BU3}82 83 %%84 %% For managing citations, it is recommended to use bibliography85 %% files in BibTeX format.86 %%87 %% You can then either use BibTeX with the ACM-Reference-Format style,88 %% or BibLaTeX with the acmnumeric or acmauthoryear sytles, that include89 %% support for advanced citation of software artefact from the90 %% biblatex-software package, also separately available on CTAN.91 %%92 %% Look at the sample-*-biblatex.tex files for templates showcasing93 %% the biblatex styles.94 %%95 96 %%97 %% The majority of ACM publications use numbered citations and98 %% references. The command \citestyle{authoryear} switches to the99 %% "author year" style.100 %%101 %% If you are preparing content for an event102 %% sponsored by ACM SIGGRAPH, you must use the "author year" style of103 %% citations and references.104 %% Uncommenting105 %% the next command will enable that style.106 %%\citestyle{acmauthoryear}107 108 75 %% 109 76 %% end of the preamble, start of the body of the document source. … … 128 95 %% article. 129 96 \begin{abstract} 130 An enumeration, or enum in short, is a type that defines a list of named constant values in C. C forall extends the enumeration with additional features.97 An enumeration, or enum in short, is a type that defines a list of named constant values in C. C uses integral type as the underlying representation of enum. Cforall extends C enum to allow more types, including custom types, to be used as enumeration inner representation. 131 98 \end{abstract} 132 99 … … 143 110 144 111 \section{C-Style Enum} 112 \begin{lstlisting}[style=CStyle, label{lst:weekday}] 113 enum Weekday { Monday, Tuesday, Wednesday, Thursday=10, Friday, Saturday, Sunday }; 114 \end{lstlisting} 115 Cforall supports the C-Style enumeration (C-enum for short). It has the same syntax as C and resembles the same language semantics. In code~\ref{lst:weekday} example, the syntax defines an enum class $Weekday$ with enumerators $Monday$, $Tuesday$, $Wednesday$, $Thursday$, $Friday$, $Saturday$ and $Sunday$ in order. The successor of $Tuesday$ is $Monday$ and the predecessor of $Tuesday$ is $Wednesday$. Enumerators have an integral type, either being explicitly initialized by an initializer or being assigned a value by the compiler. For example, $Thursday$ has been assigned with value $10$. If not explicitly initialized, the first value of an enum, $Monday$ in the $Weekday$ example, has the integer value 0. Other uninitialized enum value has a value that is equal to their successor $+ 1$. The enum value $Tuesday$, $Wednesday$, $Friday$, $Saturday$, and $Sunday$ have value 1, 2, 11, 12, and 13 respectively. 116 117 \begin{lstlisting}[label{lst:enum_scope}, style=CStyle] 118 { 119 { 120 enum RGB {R, G, B}; 121 int i = R // i == 0 122 } 123 int j = G; // ERROR! G is not declared in this scope 124 } 125 \end{lstlisting} 126 C-enums are unscoped: enumerators declared inside of an enum are visible in the enclosing scope of the enum class. 127 128 \section{Cforall-Style Enum} 129 \begin{lstlisting}[style=CStyle, label{lst:color}] 130 enum Color(char *) { Red="R", Green="G", Blue="B" }; 131 \end{lstlisting} 132 A Cforall enumeration is parameterized by a type declared. Cforall allows any oType in the enum declaration, and values assigned to enumerators must be in the declared type. 133 134 \section{Enumerable Type Traits} 135 A trait is a collection of constraints in Cforall, which can be used to describe types. Cforall standard library defines traits to categorize types that are related enumeration features. 136 \subsection{Enumerable} 137 A type is enumerable if it can map an integer to a value. 145 138 \begin{lstlisting}[style=CStyle] 146 enum Weekday { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }; 147 \end{lstlisting} 148 Cforall supports the classic C-Style enumeration (C-enum for short) and its syntax is consistent with C. No internal data structure is generated for C-enum, and C-enum does not provide the Cforall-enum interface methods. 149 150 \section{Cforall Enum} 139 forall(T) 140 trait Enumerable { 141 T value( *class_name* , int ); 142 }; 143 \end{lstlisting} 144 The parameter class name stands for the name of an enumeration class, Weekday, for example. 145 146 \subsection{AutoInitializable} 147 \begin{lstlisting}[style=CStyle] 148 forall(T) 149 trait AutoInitializable { 150 void ?()( T & t, zero_t ); 151 void ?()( T & t, one_t ); 152 S& ?+=?( T & t, one_t ); 153 void ?{}( T &, T ); 154 T ?{}( T &, T ); 155 }; 156 \end{lstlisting} 157 158 \subsection{AutoInitializable} 159 \begin{lstlisting}[style=CStyle] 160 forall(T) 161 trait AutoInitializable { 162 void ?()( T & t, zero_t ); 163 void ?()( T & t, one_t ); 164 S& ?+=?( T & t, one_t ); 165 void ?{}( T &, T ); 166 T ?{}( T &, T ); 167 }; 168 \end{lstlisting} 169 A type is AutoInitializable if it has defined a zero\_t constructor, a one\_t constructor, an addition assignment operator, a copy constructor, and a copy assignment operator. 170 151 171 \subsection{Enumerable Type} 152 172 \begin{lstlisting}[style=CStyle] … … 160 180 }; 161 181 \end{lstlisting} 162 A type is enumerable in Cforall if it has defined 0, 1, increment operator, copy constructor, and copy assignment operator. 182 183 184 185 163 186 164 187 (Should change the definition of enumerable to something else. Maybe auto-constructible. If a type is not auto-constructible, all enumeration must be explicitly initialized) … … 224 247 Names of labels are distinct in an enum declaration. Cforall therefore allows indexing an enum value with its string representation of a label. 225 248 226 \subsection{Range Functions and Iteration (Placeholder)} 249 \subsection{Iteration and Range} 250 A Cforall enum is iterable and supports range function. 227 251 \begin{lstlisting}[caption={Range Functions}, label{lst:range_functions}, style=CStyle] 228 enum Weekday( 229 Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday 230 }; 252 struct string; 253 enum(string) Weekday( 254 Monday = "M", Tuesday = "Tu", ... 255 }; 256 for ( i; Weekday ) { sout | i; } 257 >> M Tu W Th F Sat Sun 258 for ( Monday ~= Tuesday ) 259 >> M Tu 231 260 \end{lstlisting} 232 261 … … 249 278 } 250 279 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 280 enum Color.Label; 251 281 Companion( string ) Color = { 252 282 .values = [ "Red", "Green", "Blue" ], … … 255 285 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 256 286 forall( T | enumerable(T) ) 257 T* value( Companion, int ); 258 char* label( Companion, int ); 259 \end{lstlisting} 260 261 \subsection{TODO - Type trait for Cforall - Enum} 287 T value( Companion companion, int index ) { return companion.values[ index ]; } 288 T value( Companion, enum Color.Label ); 289 char* label( Companion companion, int index ) { return companion.values[ index ]; } 290 char* label( Companion, enum Color.Label ); 291 292 \end{lstlisting} 293 294 295 \subsection{Companion Trait} 296 Users can define the companion object themselves. A companion object should define an array of any type called values and an array of strings representing a label. Defining a companion object effectively creates a new enumerable type. 297 298 \subsection{Companion Mapping} 299 300 301 302 \begin{lstlisting}[caption={Enum Type Functions}, label{lst:cforall_enum_functions}, style=CStyle] 303 304 \end{lstlisting} 262 305 %% 263 306 %% If your work has an appendix, this is the place to put it. -
src/CodeTools/DeclStats.cc
r2bf46a5 r1b41219 25 25 #include "Common/PassVisitor.h" 26 26 #include "Common/VectorMap.h" // for VectorMap 27 #include "GenPoly/GenPoly.h" // for hasPolyBase28 27 #include "SynTree/LinkageSpec.h" // for ::NoOfSpecs, Spec 29 28 #include "SynTree/Declaration.h" // for FunctionDecl, TypeDecl, Declaration -
src/GenPoly/BoxNew.cpp
r2bf46a5 r1b41219 39 39 40 40 namespace { 41 42 /// Common field of several sub-passes of box.43 struct BoxPass {44 TypeVarMap scopeTypeVars;45 BoxPass() : scopeTypeVars( ast::TypeData() ) {}46 };47 41 48 42 // TODO: Could this be a common helper somewhere? … … 359 353 /// * Adds appropriate type variables to the function calls. 360 354 struct CallAdapter final : 361 public BoxPass,362 355 public ast::WithConstTypeSubstitution, 363 356 public ast::WithGuards, … … 376 369 ast::Expr const * postvisit( ast::AddressExpr const * expr ); 377 370 ast::ReturnStmt const * previsit( ast::ReturnStmt const * stmt ); 378 void previsit( ast::PointerType const * type );379 void previsit( ast::FunctionType const * type );380 371 381 372 void beginScope(); … … 386 377 // return value. 387 378 388 /// Pass the extra type parameters from polymorphic generic arguments or 389 /// return types into a function application. 390 ast::vector<ast::Expr>::iterator passArgTypeVars( 391 ast::ApplicationExpr * expr, ast::Type const * parmType, 392 ast::Type const * argBaseType, ast::vector<ast::Expr>::iterator arg, 393 const TypeVarMap & exprTyVars, std::set<std::string> & seenTypes ); 394 /// Passes extra type parameters into a polymorphic function application. 379 /// Passes extra layout arguments for sized polymorphic type parameters. 395 380 ast::vector<ast::Expr>::iterator passTypeVars( 396 381 ast::ApplicationExpr * expr, 397 ast::Type const * polyRetType, 398 ast::FunctionType const * funcType, 399 const TypeVarMap & exprTyVars ); 382 ast::FunctionType const * funcType ); 400 383 /// Wraps a function application with a new temporary for the 401 384 /// out-parameter return value. … … 448 431 CodeLocation const & location, ast::Type const * type ); 449 432 450 /// Set of adapter functions in the current scope.433 TypeVarMap scopeTypeVars; 451 434 ScopedMap< std::string, ast::DeclWithType const * > adapters; 452 435 std::map< ast::ApplicationExpr const *, ast::Expr const * > retVals; … … 561 544 562 545 ast::FunctionDecl const * CallAdapter::previsit( ast::FunctionDecl const * decl ) { 546 // Prevent type declaration information from leaking out. 547 GuardScope( scopeTypeVars ); 548 563 549 if ( nullptr == decl->stmts ) { 564 // This may keep TypeDecls we don't ever want from sneaking in.565 // Not visiting child nodes might just be faster.566 GuardScope( scopeTypeVars );567 550 return decl; 568 551 } 569 552 570 GuardScope( scopeTypeVars );571 553 GuardValue( retval ); 572 554 … … 670 652 ptrdiff_t initArgCount = mutExpr->args.size(); 671 653 672 TypeVarMap exprTypeVars = { ast::TypeData() };654 TypeVarMap exprTypeVars; 673 655 // TODO: Should this take into account the variables already bound in 674 656 // scopeTypeVars ([ex] remove them from exprTypeVars)? … … 695 677 696 678 assert( typeSubs ); 697 ast::Type const * concRetType = replaceWithConcrete( dynRetType, *typeSubs );698 // Used to use dynRetType instead of concRetType; this changed so that699 // the correct type parameters are passed for return types (it should be700 // the concrete type's parameters, not the formal type's).701 679 ast::vector<ast::Expr>::iterator argIt = 702 passTypeVars( mutExpr, concRetType, function, exprTypeVars);680 passTypeVars( mutExpr, function ); 703 681 addInferredParams( mutExpr, argIt, function, exprTypeVars ); 704 682 … … 778 756 } 779 757 780 void CallAdapter::previsit( ast::PointerType const * type ) {781 GuardScope( scopeTypeVars );782 makeTypeVarMap( type, scopeTypeVars );783 }784 785 void CallAdapter::previsit( ast::FunctionType const * type ) {786 GuardScope( scopeTypeVars );787 makeTypeVarMap( type, scopeTypeVars );788 }789 790 758 void CallAdapter::beginScope() { 791 759 adapters.beginScope(); … … 812 780 } 813 781 814 // arg is an in/out parameter that matches the return value.815 ast::vector<ast::Expr>::iterator CallAdapter::passArgTypeVars(816 ast::ApplicationExpr * expr, ast::Type const * paramType,817 ast::Type const * argBaseType, ast::vector<ast::Expr>::iterator arg,818 const TypeVarMap & exprTypeVars, std::set<std::string> & seenTypes ) {819 ast::Type const * polyType = isPolyType( paramType, exprTypeVars );820 if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) {821 return arg;822 }823 824 std::string typeName = Mangle::mangleType( polyType );825 if ( seenTypes.count( typeName ) ) return arg;826 827 arg = expr->args.insert( arg,828 new ast::SizeofExpr( expr->location, ast::deepCopy( argBaseType ) )829 );830 arg++;831 arg = expr->args.insert( arg,832 new ast::AlignofExpr( expr->location, ast::deepCopy( argBaseType ) )833 );834 arg++;835 if ( dynamic_cast<ast::StructInstType const *>( polyType ) ) {836 auto argBaseStructType =837 dynamic_cast<ast::StructInstType const *>( argBaseType );838 if ( nullptr == argBaseStructType ) {839 SemanticError( expr,840 "Cannot pass non-structure type for generic struct: " );841 }842 843 // Zero-length arrays are forbidden by C, so don't pass844 // offset for empty structure.845 if ( !argBaseStructType->base->members.empty() ) {846 arg = expr->args.insert( arg,847 new ast::OffsetPackExpr(848 expr->location,849 ast::deepCopy( argBaseStructType ) )850 );851 arg++;852 }853 }854 855 seenTypes.insert( typeName );856 return arg;857 }858 859 782 ast::vector<ast::Expr>::iterator CallAdapter::passTypeVars( 860 783 ast::ApplicationExpr * expr, 861 ast::Type const * polyRetType, 862 ast::FunctionType const * function, 863 const TypeVarMap & exprTypeVars ) { 784 ast::FunctionType const * function ) { 864 785 assert( typeSubs ); 865 786 ast::vector<ast::Expr>::iterator arg = expr->args.begin(); … … 880 801 new ast::AlignofExpr( expr->location, ast::deepCopy( concrete ) ) ); 881 802 arg++; 882 }883 884 // Add size/align for generic types to parameter list.885 if ( !expr->func->result ) return arg;886 ast::FunctionType const * funcType = getFunctionType( expr->func->result );887 assert( funcType );888 889 // This iterator points at first original argument.890 ast::vector<ast::Expr>::const_iterator funcArg;891 // Names for generic types we've seen.892 std::set<std::string> seenTypes;893 894 // A polymorphic return type may need to be added to the argument list.895 if ( polyRetType ) {896 assert( typeSubs );897 auto concRetType = replaceWithConcrete( polyRetType, *typeSubs );898 // TODO: This write-back may not be correct.899 arg = passArgTypeVars( expr, polyRetType, concRetType,900 arg, exprTypeVars, seenTypes );901 // Skip the return parameter in the argument list.902 funcArg = arg + 1;903 } else {904 funcArg = arg;905 }906 907 // TODO:908 // I believe this is (starts as) the number of original arguments to the909 // function with the args before funcArg all being inserted.910 ptrdiff_t argsToPass = std::distance( funcArg, expr->args.cend() );911 912 // Add type information args for presently unseen types in parameter list.913 ast::vector<ast::Type>::const_iterator funcParam = funcType->params.begin();914 // assert( funcType->params.size() == argsToPass );915 for ( ; funcParam != funcType->params.end() && 0 < argsToPass916 ; ++funcParam, --argsToPass ) {917 assert( 0 < argsToPass );918 assert( argsToPass <= (ptrdiff_t)expr->args.size() );919 ptrdiff_t index = expr->args.size() - argsToPass;920 ast::Type const * argType = expr->args[index]->result;921 if ( nullptr == argType ) continue;922 arg = passArgTypeVars( expr, *funcParam, argType,923 arg, exprTypeVars, seenTypes );924 803 } 925 804 return arg; … … 1523 1402 } 1524 1403 1525 ast::ObjectDecl * makePtr(1526 CodeLocation const & location, std::string const & name ) {1527 return new ast::ObjectDecl( location, name,1528 new ast::PointerType( makeSizeAlignType() ),1529 nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr );1530 }1531 1532 1404 ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) { 1533 TypeVarMap localTypeVars = { ast::TypeData() };1405 TypeVarMap localTypeVars; 1534 1406 makeTypeVarMap( decl, localTypeVars ); 1535 1407 … … 1584 1456 mutDecl->assertions.clear(); 1585 1457 1586 // Add size/align for generic parameter types to parameter list.1587 std::set<std::string> seenTypes;1588 ast::vector<ast::DeclWithType> otypeParams;1589 for ( ast::ptr<ast::DeclWithType> & funcParam : mutDecl->params ) {1590 ast::Type const * polyType = isPolyType( funcParam->get_type(), localTypeVars );1591 if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) {1592 continue;1593 }1594 std::string typeName = Mangle::mangleType( polyType );1595 if ( seenTypes.count( typeName ) ) continue;1596 seenTypes.insert( typeName );1597 1598 auto sizeParam = makeObj( funcParam->location, sizeofName( typeName ) );1599 otypeParams.emplace_back( sizeParam );1600 1601 auto alignParam = makeObj( funcParam->location, alignofName( typeName ) );1602 otypeParams.emplace_back( alignParam );1603 1604 // Zero-length arrays are illegal in C, so empty structs have no1605 // offset array.1606 if ( auto * polyStruct =1607 dynamic_cast<ast::StructInstType const *>( polyType ) ;1608 polyStruct && !polyStruct->base->members.empty() ) {1609 auto offsetParam = makePtr( funcParam->location, offsetofName( typeName ) );1610 otypeParams.emplace_back( offsetParam );1611 }1612 }1613 1614 1458 // Prepend each argument group. From last group to first. addAdapters 1615 1459 // does do the same, it just does it itself and see all other parameters. 1616 1460 spliceBegin( mutDecl->params, inferredParams ); 1617 spliceBegin( mutDecl->params, otypeParams );1618 1461 spliceBegin( mutDecl->params, layoutParams ); 1619 1462 addAdapters( mutDecl, localTypeVars ); … … 1708 1551 assertf( it != adapters.end(), "Could not correct floating node." ); 1709 1552 return ast::mutate_field( expr, &ast::VariableExpr::var, it->second ); 1710 1711 1553 } 1712 1554 … … 1720 1562 /// * Inserts dynamic calculation of polymorphic type layouts where needed. 1721 1563 struct PolyGenericCalculator final : 1722 public BoxPass,1723 1564 public ast::WithConstTypeSubstitution, 1724 1565 public ast::WithDeclsToAdd<>, … … 1728 1569 PolyGenericCalculator(); 1729 1570 1730 void previsit( ast::ObjectDecl const * decl );1731 1571 void previsit( ast::FunctionDecl const * decl ); 1732 1572 void previsit( ast::TypedefDecl const * decl ); … … 1735 1575 ast::StructDecl const * previsit( ast::StructDecl const * decl ); 1736 1576 ast::UnionDecl const * previsit( ast::UnionDecl const * decl ); 1737 void previsit( ast::PointerType const * type );1738 void previsit( ast::FunctionType const * type );1739 1577 ast::DeclStmt const * previsit( ast::DeclStmt const * stmt ); 1740 1578 ast::Expr const * postvisit( ast::MemberExpr const * expr ); … … 1768 1606 /// C sizeof(). 1769 1607 ast::Expr const * genSizeof( CodeLocation const &, ast::Type const * ); 1770 1771 1608 /// Enters a new scope for type-variables, 1772 1609 /// adding the type variables from the provided type. 1773 1610 void beginTypeScope( ast::Type const * ); 1774 /// Enters a new scope for known layouts and offsets, and queues exit calls. 1775 void beginGenericScope();1776 1611 1612 /// The type variables and polymorphic parameters currently in scope. 1613 TypeVarMap scopeTypeVars; 1777 1614 /// Set of generic type layouts known in the current scope, 1778 1615 /// indexed by sizeofName. … … 1785 1622 /// If the argument of an AddressExpr is MemberExpr, it is stored here. 1786 1623 ast::MemberExpr const * addrMember = nullptr; 1787 /// Used to avoid recursing too deep in type declarations.1788 bool expect_func_type = false;1789 1624 }; 1790 1625 … … 1808 1643 } 1809 1644 1810 void PolyGenericCalculator::previsit( ast::ObjectDecl const * decl ) { 1645 void PolyGenericCalculator::previsit( ast::FunctionDecl const * decl ) { 1646 GuardScope( *this ); 1811 1647 beginTypeScope( decl->type ); 1812 }1813 1814 void PolyGenericCalculator::previsit( ast::FunctionDecl const * decl ) {1815 beginGenericScope();1816 beginTypeScope( decl->type );1817 1818 // TODO: Going though dec->params does not work for some reason.1819 for ( ast::ptr<ast::Type> const & funcParam : decl->type->params ) {1820 // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )`1821 ast::Type const * polyType = isPolyType( funcParam, scopeTypeVars );1822 if ( polyType && !dynamic_cast<ast::TypeInstType const *>( polyType ) ) {1823 knownLayouts.insert( Mangle::mangleType( polyType ) );1824 }1825 }1826 1648 } 1827 1649 … … 1838 1660 ast::TypeDecl const * decl ) { 1839 1661 ast::Type const * base = decl->base; 1840 if ( nullptr == base ) return decl;1662 if ( nullptr == base ) return decl; 1841 1663 1842 1664 // Add size/align variables for opaque type declarations. … … 1863 1685 alignDecl->accept( *visitor ); 1864 1686 1865 // Can't use [makeVar], because it inserts into stmtsToAdd and TypeDecls1866 // can occur at global scope.1687 // A little trick to replace this with two declarations. 1688 // Adding after makes sure that there is no conflict with adding stmts. 1867 1689 declsToAddAfter.push_back( alignDecl ); 1868 // replace with sizeDecl.1869 1690 return sizeDecl; 1870 1691 } … … 1884 1705 } 1885 1706 1886 void PolyGenericCalculator::previsit( ast::PointerType const * type ) {1887 beginTypeScope( type );1888 }1889 1890 void PolyGenericCalculator::previsit( ast::FunctionType const * type ) {1891 beginTypeScope( type );1892 1893 GuardValue( expect_func_type );1894 GuardScope( *this );1895 1896 // The other functions type we will see in this scope are probably1897 // function parameters they don't help us with the layout and offsets so1898 // don't mark them as known in this scope.1899 expect_func_type = false;1900 1901 // Make sure that any type information passed into the function is1902 // accounted for.1903 for ( ast::ptr<ast::Type> const & funcParam : type->params ) {1904 // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )`1905 ast::Type const * polyType = isPolyType( funcParam, scopeTypeVars );1906 if ( polyType && !dynamic_cast<ast::TypeInstType const *>( polyType ) ) {1907 knownLayouts.insert( Mangle::mangleType( polyType ) );1908 }1909 }1910 }1911 1912 //void PolyGenericCalculator::previsit( ast::DeclStmt const * stmt ) {1913 1707 ast::DeclStmt const * PolyGenericCalculator::previsit( ast::DeclStmt const * stmt ) { 1914 1708 ast::ObjectDecl const * decl = stmt->decl.as<ast::ObjectDecl>(); … … 1918 1712 1919 1713 // Change initialization of a polymorphic value object to allocate via a 1920 // variable-length-array (alloca was previouly used, but it cannot be 1921 // safely used in loops). 1714 // variable-length-array (alloca cannot be safely used in loops). 1922 1715 ast::ObjectDecl * newBuf = new ast::ObjectDecl( decl->location, 1923 1716 bufNamer.newName(), … … 2400 2193 } 2401 2194 2402 void PolyGenericCalculator::beginGenericScope() {2403 GuardScope( *this );2404 // We expect the first function type see to be the type relating to this2405 // scope but any further type is probably some unrelated function pointer2406 // keep track of whrich is the first.2407 GuardValue( expect_func_type ) = true;2408 }2409 2410 2195 // -------------------------------------------------------------------------- 2411 /// No common theme found.2196 /// Removes unneeded or incorrect type information. 2412 2197 /// * Replaces initialization of polymorphic values with alloca. 2413 2198 /// * Replaces declaration of dtype/ftype with appropriate void expression. … … 2415 2200 /// * Strips fields from generic structure declarations. 2416 2201 struct Eraser final : 2417 public BoxPass,2418 2202 public ast::WithGuards { 2419 2203 void guardTypeVarMap( ast::Type const * type ) { … … 2430 2214 void previsit( ast::PointerType const * type ); 2431 2215 void previsit( ast::FunctionType const * type ); 2216 public: 2217 TypeVarMap scopeTypeVars; 2432 2218 }; 2433 2219 -
src/GenPoly/GenPoly.cc
r2bf46a5 r1b41219 273 273 if ( func->returns.empty() ) return nullptr; 274 274 275 TypeVarMap forallTypes = { ast::TypeData() };275 TypeVarMap forallTypes; 276 276 makeTypeVarMap( func, forallTypes ); 277 277 return isDynType( func->returns.front(), forallTypes ); … … 801 801 const ast::FunctionType * function = getFunctionType( expr->func->result ); 802 802 assertf( function, "ApplicationExpr has non-function type: %s", toString( expr->func->result ).c_str() ); 803 TypeVarMap exprTyVars = { ast::TypeData() };803 TypeVarMap exprTyVars; 804 804 makeTypeVarMap( function, exprTyVars ); 805 805 return needsBoxing( param, arg, exprTyVars, subst ); -
src/GenPoly/GenPoly.h
r2bf46a5 r1b41219 33 33 34 34 typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap; 35 using TypeVarMap = ErasableScopedMap< ast::TypeEnvKey, ast::TypeData >; 35 struct TypeVarMap : public ErasableScopedMap<ast::TypeEnvKey, ast::TypeData> { 36 TypeVarMap() : ErasableScopedMap( ast::TypeData() ) {} 37 }; 36 38 37 39 /// Replaces a TypeInstType by its referrent in the environment, if applicable -
src/GenPoly/SpecializeNew.cpp
r2bf46a5 r1b41219 81 81 } 82 82 83 // The number of elements in a type if it is a flattened tuple.84 size_t flatT upleSize( const ast::Type * type) {85 if ( auto tuple = dynamic_cast<const ast::TupleType *>( type ) ) {86 size_t sum = 0;87 for ( auto t : *tuple) {88 sum += flatT upleSize( t);89 } 90 return sum;91 } else {92 return 1;93 }83 // The number of elements in a list, if all tuples had been flattened. 84 size_t flatTypeListSize( const std::vector<ast::ptr<ast::Type>> & types ) { 85 size_t sum = 0; 86 for ( const ast::ptr<ast::Type> & type : types ) { 87 if ( const ast::TupleType * tuple = type.as<ast::TupleType>() ) { 88 sum += flatTypeListSize( tuple->types ); 89 } else { 90 sum += 1; 91 } 92 } 93 return sum; 94 94 } 95 95 96 96 // Find the total number of components in a parameter list. 97 97 size_t functionParameterSize( const ast::FunctionType * type ) { 98 size_t sum = 0; 99 for ( auto param : type->params ) { 100 sum += flatTupleSize( param ); 101 } 102 return sum; 98 return flatTypeListSize( type->params ); 103 99 } 104 100
Note: See TracChangeset
for help on using the changeset viewer.