Ignore:
Timestamp:
Jun 26, 2023, 10:51:47 AM (2 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

File:
1 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
Note: See TracChangeset for help on using the changeset viewer.