Changeset 48ec19a for src/Validate


Ignore:
Timestamp:
Jun 26, 2023, 10:51:47 AM (3 years ago)
Author:
caparson <caparson@…>
Branches:
master
Children:
917e1fd
Parents:
adc73a5 (diff), 1fbf481 (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

Location:
src/Validate
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/Validate/GenericParameter.cpp

    radc73a5 r48ec19a  
    1616#include "GenericParameter.hpp"
    1717
    18 #include "AST/Copy.hpp"
    1918#include "AST/Decl.hpp"
    2019#include "AST/Expr.hpp"
     
    120119}
    121120
    122 struct ValidateGenericParamsCore : public ast::WithCodeLocation {
     121bool isSizedPolymorphic( const ast::AggregateDecl * decl ) {
     122        for ( const auto & param : decl->params ) {
     123                if ( param->sized ) return true;
     124        }
     125        return false;
     126}
     127
     128struct ValidateGenericParamsCore :
     129                public ast::WithCodeLocation, public ast::WithGuards {
     130        // Generic parameter filling and checks:
    123131        const ast::StructInstType * previsit( const ast::StructInstType * type ) {
    124132                assert( location );
     
    130138                return validateGeneric( *location, type );
    131139        }
     140
     141        // Check parameter and bitfield combinations:
     142        bool insideSized = false;
     143        void previsit( const ast::StructDecl * decl ) {
     144                if ( isSizedPolymorphic( decl ) && !insideSized ) {
     145                        GuardValue( insideSized ) = true;
     146                }
     147        }
     148
     149        void previsit( const ast::UnionDecl * decl ) {
     150                if ( isSizedPolymorphic( decl ) && !insideSized ) {
     151                        GuardValue( insideSized ) = true;
     152                }
     153        }
     154
     155        void previsit( const ast::ObjectDecl * decl ) {
     156                if ( insideSized && decl->bitfieldWidth ) {
     157                        SemanticError( decl->location, decl,
     158                                "Cannot have bitfields inside a sized polymorphic structure." );
     159                }
     160        }
    132161};
    133162
     
    135164
    136165struct TranslateDimensionCore :
    137                 public WithNoIdSymbolTable, public ast::WithGuards {
     166                public WithNoIdSymbolTable, public ast::WithGuards,
     167                public ast::WithVisitorRef<TranslateDimensionCore> {
    138168
    139169        // SUIT: Struct- or Union- InstType
     
    160190
    161191        const ast::TypeDecl * postvisit( const ast::TypeDecl * decl );
     192        const ast::Type * postvisit( const ast::FunctionType * type );
     193        const ast::Type * postvisit( const ast::TypeInstType * type );
     194
    162195        const ast::Expr * postvisit( const ast::DimensionExpr * expr );
    163196        const ast::Expr * postvisit( const ast::Expr * expr );
     
    165198};
    166199
     200// Declaration of type variable: forall( [N] )  ->  forall( N & | sized( N ) )
    167201const ast::TypeDecl * TranslateDimensionCore::postvisit(
    168202                const ast::TypeDecl * decl ) {
     
    176210        }
    177211        return decl;
     212}
     213
     214// Makes postvisit( TypeInstType ) get called on the entries of the function declaration's type's forall list.
     215// Pass.impl.hpp's visit( FunctionType ) does not consider the forall entries to be child nodes.
     216// Workaround is: during the current TranslateDimension pass, manually visit down there.
     217const ast::Type * TranslateDimensionCore::postvisit(
     218                const ast::FunctionType * type ) {
     219        visitor->maybe_accept( type, &ast::FunctionType::forall );
     220        return type;
     221}
     222
     223// Use of type variable, assuming `forall( [N] )` in scope:  void (*)( foo( /*dimension*/ N ) & )  ->  void (*)( foo( /*dtype*/ N ) & )
     224const ast::Type * TranslateDimensionCore::postvisit(
     225                const ast::TypeInstType * type ) {
     226        if ( type->kind == ast::TypeDecl::Dimension ) {
     227                auto mutType = ast::mutate( type );
     228                mutType->kind = ast::TypeDecl::Dtype;
     229                return mutType;
     230        }
     231        return type;
    178232}
    179233
  • src/Validate/LinkReferenceToTypes.cpp

    radc73a5 r48ec19a  
    8484                // Just linking in the node.
    8585                auto mut = ast::mutate( type );
    86                 mut->base = const_cast<ast::EnumDecl *>( decl );
     86                mut->base = decl;
    8787                type = mut;
    8888        }
     
    101101                // Just linking in the node.
    102102                auto mut = ast::mutate( type );
    103                 mut->base = const_cast<ast::StructDecl *>( decl );
     103                mut->base = decl;
    104104                type = mut;
    105105        }
     
    118118                // Just linking in the node.
    119119                auto mut = ast::mutate( type );
    120                 mut->base = const_cast<ast::UnionDecl *>( decl );
     120                mut->base = decl;
    121121                type = mut;
    122122        }
     
    141141
    142142        // Just linking in the node.
    143         mut->base = const_cast<ast::TraitDecl *>( decl );
     143        mut->base = decl;
    144144
    145145        // Need to carry over the 'sized' status of each decl in the instance.
     
    203203        }
    204204
    205         // The following section
    206 
    207205        ForwardEnumsType::iterator fwds = forwardEnums.find( decl->name );
    208206        if ( fwds != forwardEnums.end() ) {
     
    266264
    267265ast::TraitDecl const * LinkTypesCore::postvisit( ast::TraitDecl const * decl ) {
    268         auto mut = ast::mutate( decl );
    269         if ( mut->name == "sized" ) {
    270                 // "sized" is a special trait - flick the sized status on for the type variable.
    271                 assertf( mut->params.size() == 1, "Built-in trait 'sized' has incorrect number of parameters: %zd", decl->params.size() );
    272                 ast::TypeDecl * td = mut->params.front().get_and_mutate();
    273                 td->sized = true;
    274         }
    275 
    276266        // There is some overlap with code from decayForallPointers,
    277267        // perhaps reorganization or shared helper functions are called for.
    278268        // Move assertions from type parameters into the body of the trait.
     269        auto mut = ast::mutate( decl );
    279270        for ( ast::ptr<ast::TypeDecl> const & td : decl->params ) {
    280271                auto expanded = expandAssertions( td->assertions );
Note: See TracChangeset for help on using the changeset viewer.