Changeset 1b41219


Ignore:
Timestamp:
Oct 17, 2023, 8:50:05 AM (11 months ago)
Author:
Peter A. Buhr <pabuhr@…>
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.
Message:

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

Files:
5 edited
1 moved

Legend:

Unmodified
Added
Removed
  • doc/proposals/enum.tex

    r2bf46a5 r1b41219  
    7373
    7474
    75 
    76 %%
    77 %% Submission ID.
    78 %% Use this when submitting an article to a sponsored event. You'll
    79 %% receive a unique submission ID from the organizers
    80 %% 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 bibliography
    85 %% 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 include
    89 %% support for advanced citation of software artefact from the
    90 %% biblatex-software package, also separately available on CTAN.
    91 %%
    92 %% Look at the sample-*-biblatex.tex files for templates showcasing
    93 %% the biblatex styles.
    94 %%
    95 
    96 %%
    97 %% The majority of ACM publications use numbered citations and
    98 %% references.  The command \citestyle{authoryear} switches to the
    99 %% "author year" style.
    100 %%
    101 %% If you are preparing content for an event
    102 %% sponsored by ACM SIGGRAPH, you must use the "author year" style of
    103 %% citations and references.
    104 %% Uncommenting
    105 %% the next command will enable that style.
    106 %%\citestyle{acmauthoryear}
    107 
    10875%%
    10976%% end of the preamble, start of the body of the document source.
     
    12895%% article.
    12996\begin{abstract}
    130     An enumeration, or enum in short, is a type that defines a list of named constant values in C. Cforall 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.
    13198\end{abstract}
    13299
     
    143110
    144111\section{C-Style Enum}
     112\begin{lstlisting}[style=CStyle, label{lst:weekday}]
     113enum Weekday { Monday, Tuesday, Wednesday, Thursday=10, Friday, Saturday, Sunday };
     114\end{lstlisting}
     115Cforall 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}
     126C-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}]
     130enum Color(char *) { Red="R", Green="G", Blue="B"  };
     131\end{lstlisting}
     132A 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}
     135A 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}
     137A type is enumerable if it can map an integer to a value.
    145138\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}
     139forall(T)
     140trait Enumerable {
     141    T value( *class_name* , int );
     142};
     143\end{lstlisting}
     144The parameter class name stands for the name of an enumeration class, Weekday, for example.
     145
     146\subsection{AutoInitializable}
     147\begin{lstlisting}[style=CStyle]
     148forall(T)
     149trait 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]
     160forall(T)
     161trait 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}
     169A 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
    151171\subsection{Enumerable Type}
    152172\begin{lstlisting}[style=CStyle]
     
    160180};
    161181\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
    163186
    164187(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)
     
    224247Names of labels are distinct in an enum declaration. Cforall therefore allows indexing an enum value with its string representation of a label.
    225248
    226 \subsection{Range Functions and Iteration (Placeholder)}
     249\subsection{Iteration and Range}
     250A Cforall enum is iterable and supports range function.
    227251\begin{lstlisting}[caption={Range Functions}, label{lst:range_functions}, style=CStyle]
    228 enum Weekday(
    229     Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
    230 };
     252struct string;
     253enum(string) Weekday(
     254    Monday = "M", Tuesday = "Tu", ...
     255};
     256for ( i; Weekday ) { sout | i; }
     257>> M Tu W Th F Sat Sun
     258for ( Monday ~= Tuesday )
     259>> M Tu
    231260\end{lstlisting}
    232261
     
    249278}
    250279>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
     280enum Color.Label;
    251281Companion( string ) Color = {
    252282    .values = [ "Red", "Green", "Blue" ],
     
    255285>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    256286forall( 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}
     287T value( Companion companion, int index ) { return companion.values[ index ]; }
     288T value( Companion, enum Color.Label );
     289char* label( Companion companion, int index ) { return companion.values[ index ]; }
     290char* label( Companion, enum Color.Label );
     291
     292\end{lstlisting}
     293
     294
     295\subsection{Companion Trait}
     296Users 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}
    262305%%
    263306%% If your work has an appendix, this is the place to put it.
  • src/CodeTools/DeclStats.cc

    r2bf46a5 r1b41219  
    2525#include "Common/PassVisitor.h"
    2626#include "Common/VectorMap.h"      // for VectorMap
    27 #include "GenPoly/GenPoly.h"       // for hasPolyBase
    2827#include "SynTree/LinkageSpec.h"   // for ::NoOfSpecs, Spec
    2928#include "SynTree/Declaration.h"   // for FunctionDecl, TypeDecl, Declaration
  • src/GenPoly/BoxNew.cpp

    r2bf46a5 r1b41219  
    3939
    4040namespace {
    41 
    42 /// Common field of several sub-passes of box.
    43 struct BoxPass {
    44         TypeVarMap scopeTypeVars;
    45         BoxPass() : scopeTypeVars( ast::TypeData() ) {}
    46 };
    4741
    4842// TODO: Could this be a common helper somewhere?
     
    359353/// * Adds appropriate type variables to the function calls.
    360354struct CallAdapter final :
    361                 public BoxPass,
    362355                public ast::WithConstTypeSubstitution,
    363356                public ast::WithGuards,
     
    376369        ast::Expr const * postvisit( ast::AddressExpr const * expr );
    377370        ast::ReturnStmt const * previsit( ast::ReturnStmt const * stmt );
    378         void previsit( ast::PointerType const * type );
    379         void previsit( ast::FunctionType const * type );
    380371
    381372        void beginScope();
     
    386377        // return value.
    387378
    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.
    395380        ast::vector<ast::Expr>::iterator passTypeVars(
    396381                ast::ApplicationExpr * expr,
    397                 ast::Type const * polyRetType,
    398                 ast::FunctionType const * funcType,
    399                 const TypeVarMap & exprTyVars );
     382                ast::FunctionType const * funcType );
    400383        /// Wraps a function application with a new temporary for the
    401384        /// out-parameter return value.
     
    448431                CodeLocation const & location, ast::Type const * type );
    449432
    450         /// Set of adapter functions in the current scope.
     433        TypeVarMap scopeTypeVars;
    451434        ScopedMap< std::string, ast::DeclWithType const * > adapters;
    452435        std::map< ast::ApplicationExpr const *, ast::Expr const * > retVals;
     
    561544
    562545ast::FunctionDecl const * CallAdapter::previsit( ast::FunctionDecl const * decl ) {
     546        // Prevent type declaration information from leaking out.
     547        GuardScope( scopeTypeVars );
     548
    563549        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 );
    567550                return decl;
    568551        }
    569552
    570         GuardScope( scopeTypeVars );
    571553        GuardValue( retval );
    572554
     
    670652        ptrdiff_t initArgCount = mutExpr->args.size();
    671653
    672         TypeVarMap exprTypeVars = { ast::TypeData() };
     654        TypeVarMap exprTypeVars;
    673655        // TODO: Should this take into account the variables already bound in
    674656        // scopeTypeVars ([ex] remove them from exprTypeVars)?
     
    695677
    696678        assert( typeSubs );
    697         ast::Type const * concRetType = replaceWithConcrete( dynRetType, *typeSubs );
    698         // Used to use dynRetType instead of concRetType; this changed so that
    699         // the correct type parameters are passed for return types (it should be
    700         // the concrete type's parameters, not the formal type's).
    701679        ast::vector<ast::Expr>::iterator argIt =
    702                 passTypeVars( mutExpr, concRetType, function, exprTypeVars );
     680                passTypeVars( mutExpr, function );
    703681        addInferredParams( mutExpr, argIt, function, exprTypeVars );
    704682
     
    778756}
    779757
    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 
    790758void CallAdapter::beginScope() {
    791759        adapters.beginScope();
     
    812780}
    813781
    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 pass
    844                 // 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 
    859782ast::vector<ast::Expr>::iterator CallAdapter::passTypeVars(
    860783                ast::ApplicationExpr * expr,
    861                 ast::Type const * polyRetType,
    862                 ast::FunctionType const * function,
    863                 const TypeVarMap & exprTypeVars ) {
     784                ast::FunctionType const * function ) {
    864785        assert( typeSubs );
    865786        ast::vector<ast::Expr>::iterator arg = expr->args.begin();
     
    880801                        new ast::AlignofExpr( expr->location, ast::deepCopy( concrete ) ) );
    881802                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 the
    909         // 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 < argsToPass
    916                         ; ++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 );
    924803        }
    925804        return arg;
     
    15231402}
    15241403
    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 
    15321404ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) {
    1533         TypeVarMap localTypeVars = { ast::TypeData() };
     1405        TypeVarMap localTypeVars;
    15341406        makeTypeVarMap( decl, localTypeVars );
    15351407
     
    15841456        mutDecl->assertions.clear();
    15851457
    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 no
    1605                 // 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 
    16141458        // Prepend each argument group. From last group to first. addAdapters
    16151459        // does do the same, it just does it itself and see all other parameters.
    16161460        spliceBegin( mutDecl->params, inferredParams );
    1617         spliceBegin( mutDecl->params, otypeParams );
    16181461        spliceBegin( mutDecl->params, layoutParams );
    16191462        addAdapters( mutDecl, localTypeVars );
     
    17081551        assertf( it != adapters.end(), "Could not correct floating node." );
    17091552        return ast::mutate_field( expr, &ast::VariableExpr::var, it->second );
    1710 
    17111553}
    17121554
     
    17201562/// * Inserts dynamic calculation of polymorphic type layouts where needed.
    17211563struct PolyGenericCalculator final :
    1722                 public BoxPass,
    17231564                public ast::WithConstTypeSubstitution,
    17241565                public ast::WithDeclsToAdd<>,
     
    17281569        PolyGenericCalculator();
    17291570
    1730         void previsit( ast::ObjectDecl const * decl );
    17311571        void previsit( ast::FunctionDecl const * decl );
    17321572        void previsit( ast::TypedefDecl const * decl );
     
    17351575        ast::StructDecl const * previsit( ast::StructDecl const * decl );
    17361576        ast::UnionDecl const * previsit( ast::UnionDecl const * decl );
    1737         void previsit( ast::PointerType const * type );
    1738         void previsit( ast::FunctionType const * type );
    17391577        ast::DeclStmt const * previsit( ast::DeclStmt const * stmt );
    17401578        ast::Expr const * postvisit( ast::MemberExpr const * expr );
     
    17681606        /// C sizeof().
    17691607        ast::Expr const * genSizeof( CodeLocation const &, ast::Type const * );
    1770 
    17711608        /// Enters a new scope for type-variables,
    17721609        /// adding the type variables from the provided type.
    17731610        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;
    17771614        /// Set of generic type layouts known in the current scope,
    17781615        /// indexed by sizeofName.
     
    17851622        /// If the argument of an AddressExpr is MemberExpr, it is stored here.
    17861623        ast::MemberExpr const * addrMember = nullptr;
    1787         /// Used to avoid recursing too deep in type declarations.
    1788         bool expect_func_type = false;
    17891624};
    17901625
     
    18081643}
    18091644
    1810 void PolyGenericCalculator::previsit( ast::ObjectDecl const * decl ) {
     1645void PolyGenericCalculator::previsit( ast::FunctionDecl const * decl ) {
     1646        GuardScope( *this );
    18111647        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         }
    18261648}
    18271649
     
    18381660                ast::TypeDecl const * decl ) {
    18391661        ast::Type const * base = decl->base;
    1840         if ( nullptr == base) return decl;
     1662        if ( nullptr == base ) return decl;
    18411663
    18421664        // Add size/align variables for opaque type declarations.
     
    18631685        alignDecl->accept( *visitor );
    18641686
    1865         // Can't use [makeVar], because it inserts into stmtsToAdd and TypeDecls
    1866         // 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.
    18671689        declsToAddAfter.push_back( alignDecl );
    1868         // replace with sizeDecl.
    18691690        return sizeDecl;
    18701691}
     
    18841705}
    18851706
    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 probably
    1897         // function parameters they don't help us with the layout and offsets so
    1898         // 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 is
    1902         // 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 ) {
    19131707ast::DeclStmt const * PolyGenericCalculator::previsit( ast::DeclStmt const * stmt ) {
    19141708        ast::ObjectDecl const * decl = stmt->decl.as<ast::ObjectDecl>();
     
    19181712
    19191713        // 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).
    19221715        ast::ObjectDecl * newBuf = new ast::ObjectDecl( decl->location,
    19231716                bufNamer.newName(),
     
    24002193}
    24012194
    2402 void PolyGenericCalculator::beginGenericScope() {
    2403         GuardScope( *this );
    2404         // We expect the first function type see to be the type relating to this
    2405         // scope but any further type is probably some unrelated function pointer
    2406         // keep track of whrich is the first.
    2407         GuardValue( expect_func_type ) = true;
    2408 }
    2409 
    24102195// --------------------------------------------------------------------------
    2411 /// No common theme found.
     2196/// Removes unneeded or incorrect type information.
    24122197/// * Replaces initialization of polymorphic values with alloca.
    24132198/// * Replaces declaration of dtype/ftype with appropriate void expression.
     
    24152200/// * Strips fields from generic structure declarations.
    24162201struct Eraser final :
    2417                 public BoxPass,
    24182202                public ast::WithGuards {
    24192203        void guardTypeVarMap( ast::Type const * type ) {
     
    24302214        void previsit( ast::PointerType const * type );
    24312215        void previsit( ast::FunctionType const * type );
     2216public:
     2217        TypeVarMap scopeTypeVars;
    24322218};
    24332219
  • src/GenPoly/GenPoly.cc

    r2bf46a5 r1b41219  
    273273        if ( func->returns.empty() ) return nullptr;
    274274
    275         TypeVarMap forallTypes = { ast::TypeData() };
     275        TypeVarMap forallTypes;
    276276        makeTypeVarMap( func, forallTypes );
    277277        return isDynType( func->returns.front(), forallTypes );
     
    801801        const ast::FunctionType * function = getFunctionType( expr->func->result );
    802802        assertf( function, "ApplicationExpr has non-function type: %s", toString( expr->func->result ).c_str() );
    803         TypeVarMap exprTyVars = { ast::TypeData() };
     803        TypeVarMap exprTyVars;
    804804        makeTypeVarMap( function, exprTyVars );
    805805        return needsBoxing( param, arg, exprTyVars, subst );
  • src/GenPoly/GenPoly.h

    r2bf46a5 r1b41219  
    3333
    3434        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        };
    3638
    3739        /// Replaces a TypeInstType by its referrent in the environment, if applicable
  • src/GenPoly/SpecializeNew.cpp

    r2bf46a5 r1b41219  
    8181}
    8282
    83 // The number of elements in a type if it is a flattened tuple.
    84 size_t flatTupleSize( 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 += flatTupleSize( 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.
     84size_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;
    9494}
    9595
    9696// Find the total number of components in a parameter list.
    9797size_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 );
    10399}
    104100
Note: See TracChangeset for help on using the changeset viewer.