Changeset 2a301ff for src/Validate


Ignore:
Timestamp:
Aug 31, 2023, 11:31:15 PM (2 years ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
950c58e
Parents:
92355883 (diff), 686912c (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:

Resolve conflict

Location:
src/Validate
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/Validate/Autogen.cpp

    r92355883 r2a301ff  
    532532                )
    533533        );
    534         return genImplicitCall(
     534        auto stmt = genImplicitCall(
    535535                srcParam, dstSelect, location, func->name,
    536536                field, direction
    537537        );
     538        // This could return the above directly, except the generated code is
     539        // built using the structure's members and that means all the scoped
     540        // names (the forall parameters) are incorrect. This corrects them.
     541        if ( stmt && !decl->params.empty() ) {
     542                ast::DeclReplacer::TypeMap oldToNew;
     543                for ( auto pair : group_iterate( decl->params, func->type_params ) ) {
     544                        oldToNew.emplace( std::get<0>(pair), std::get<1>(pair) );
     545                }
     546                auto node = ast::DeclReplacer::replace( stmt, oldToNew );
     547                stmt = strict_dynamic_cast<const ast::Stmt *>( node );
     548        }
     549        return stmt;
    538550}
    539551
  • src/Validate/FixQualifiedTypes.cpp

    r92355883 r2a301ff  
    8989        }
    9090
    91         ast::Expr const * postvisit( ast::QualifiedNameExpr const * t) {
     91        ast::Expr const * postvisit( ast::QualifiedNameExpr const * t ) {
    9292                assert( location );
    93                 if ( t->type_decl ) {
    94                 auto enumName = t->type_decl->name;
    95                 const ast::EnumDecl * enumDecl = symtab.lookupEnum( enumName );
    96                         for ( ast::ptr<ast::Decl> const & member : enumDecl->members ) {
    97                                 if ( auto memberAsObj = member.as<ast::ObjectDecl>() ) {
    98                                         if ( memberAsObj->name == t->name ) {
    99                                                 return new ast::VariableExpr( t->location, memberAsObj );
    100                                         }
    101                                 } else {
    102                                         assertf( false, "unhandled qualified child type");
     93                if ( !t->type_decl ) return t;
     94
     95                auto enumName = t->type_decl->name;
     96                const ast::EnumDecl * enumDecl = symtab.lookupEnum( enumName );
     97                for ( ast::ptr<ast::Decl> const & member : enumDecl->members ) {
     98                        if ( auto memberAsObj = member.as<ast::ObjectDecl>() ) {
     99                                if ( memberAsObj->name == t->name ) {
     100                                        return new ast::VariableExpr( t->location, memberAsObj );
    103101                                }
     102                        } else {
     103                                assertf( false, "unhandled qualified child type" );
    104104                        }
     105                }
    105106
    106                 auto var = new ast::ObjectDecl( t->location, t->name,
    107                         new ast::EnumInstType(enumDecl, ast::CV::Const), nullptr, {}, ast::Linkage::Cforall );
    108                         var->mangleName = Mangle::mangle( var );
    109                         return new ast::VariableExpr( t->location, var );
    110         }
    111 
    112                 return t;
     107                auto var = new ast::ObjectDecl( t->location, t->name,
     108                        new ast::EnumInstType( enumDecl, ast::CV::Const ),
     109                        nullptr, {}, ast::Linkage::Cforall );
     110                var->mangleName = Mangle::mangle( var );
     111                return new ast::VariableExpr( t->location, var );
    113112        }
    114113
  • src/Validate/ForallPointerDecay.cpp

    r92355883 r2a301ff  
    2323#include "Common/CodeLocation.h"
    2424#include "Common/ToString.hpp"
     25#include "Common/utility.h"
    2526#include "SymTab/FixFunction.h"
    26 
    27 #include "AST/Print.hpp"
    2827
    2928namespace Validate {
     
    5150}
    5251
    53 template<typename T>
    54 void append( std::vector<T> & dst, std::vector<T> & src ) {
    55         dst.reserve( dst.size() + src.size() );
    56         for ( auto el : src ) {
    57                 dst.emplace_back( std::move( el ) );
    58         }
    59         src.clear();
     52ast::FunctionDecl * updateAssertions( ast::FunctionDecl * decl ) {
     53        auto type = ast::mutate( decl->type.get() );
     54        type->assertions.clear();
     55        type->assertions.reserve( decl->assertions.size() );
     56        for ( auto & assertion : decl->assertions ) {
     57                type->assertions.emplace_back(
     58                        new ast::VariableExpr( decl->location, assertion ) );
     59        }
     60        decl->type = type;
     61        return decl;
    6062}
    6163
     
    9698                                        decl->get_type() ) ) {
    9799                                auto moreAsserts = expandTrait( traitInst );
    98                                 append( assertions, moreAsserts );
     100                                splice( assertions, moreAsserts );
    99101                        } else {
    100102                                assertions.push_back( decl );
     
    108110        static TypeDeclVec expandTypeDecls( const TypeDeclVec & old ) {
    109111                TypeDeclVec typeDecls;
     112                typeDecls.reserve( old.size() );
    110113                for ( const ast::TypeDecl * typeDecl : old ) {
    111114                        typeDecls.push_back( ast::mutate_field( typeDecl,
     
    123126                mut->assertions = expandAssertions( decl->assertions );
    124127                // Update the assertion list on the type as well.
    125                 auto mutType = ast::mutate( mut->type.get() );
    126                 mutType->assertions.clear();
    127                 for ( auto & assertion : mut->assertions ) {
    128                         mutType->assertions.emplace_back(
    129                                 new ast::VariableExpr( mut->location, assertion ) );
    130                 }
    131                 mut->type = mutType;
    132                 return mut;
     128                return updateAssertions( mut );
    133129        }
    134130
     
    154150                const std::vector<ast::ptr<ast::DeclWithType>> & assertions ) {
    155151        std::vector<ast::ptr<ast::DeclWithType>> ret;
     152        ret.reserve( assertions.size() );
    156153        for ( const auto & assn : assertions ) {
    157154                bool isVoid = false;
     
    187184        }
    188185
     186        const ast::FunctionDecl * postvisit( const ast::FunctionDecl * decl ) {
     187                if ( decl->assertions.empty() ) {
     188                        return decl;
     189                }
     190                return updateAssertions( mutate( decl ) );
     191        }
     192
    189193        const ast::StructDecl * previsit( const ast::StructDecl * decl ) {
    190194                if ( decl->params.empty() ) {
     
    204208};
    205209
    206 struct OberatorChecker final {
     210struct OperatorChecker final {
    207211        void previsit( const ast::ObjectDecl * obj ) {
    208                 if ( CodeGen::isOperator( obj->name ) ) {
    209                         auto type = obj->type->stripDeclarator();
    210                         if ( ! dynamic_cast< const ast::FunctionType * >( type ) ) {
    211                                 SemanticError( obj->location,
    212                                         toCString( "operator ", obj->name.c_str(), " is not "
    213                                         "a function or function pointer." ) );
    214                         }
    215                 }
     212                if ( !CodeGen::isOperator( obj->name ) ) return;
     213                auto type = obj->type->stripDeclarator();
     214                if ( dynamic_cast< const ast::FunctionType * >( type ) ) return;
     215                SemanticError( obj->location,
     216                        toCString( "operator ", obj->name.c_str(),
     217                        " is not a function or function pointer." ) );
    216218        }
    217219};
     
    234236        ast::Pass<TraitExpander>::run( transUnit );
    235237        ast::Pass<AssertionFunctionFixer>::run( transUnit );
    236         ast::Pass<OberatorChecker>::run( transUnit );
     238        ast::Pass<OperatorChecker>::run( transUnit );
     239}
     240
     241void fixUniqueIds( ast::TranslationUnit & transUnit ) {
    237242        ast::Pass<UniqueFixCore>::run( transUnit );
    238243}
  • src/Validate/ForallPointerDecay.hpp

    r92355883 r2a301ff  
    2727
    2828/// Cleans up assertion lists and expands traits.
    29 /// Also checks that operator names are used properly on functions and
    30 /// assigns unique IDs. This is a "legacy" pass.
     29/// Also checks that operator names are used properly on functions.
     30/// This is a "legacy" pass.
     31/// Must happen before auto-gen routines are added.
     32void decayForallPointers( ast::TranslationUnit & transUnit );
     33
     34/// Sets uniqueIds on any declarations that do not have one set.
    3135/// Must be after implement concurrent keywords; because uniqueIds must be
    3236/// set on declaration before resolution.
    33 /// Must happen before auto-gen routines are added.
    34 void decayForallPointers( ast::TranslationUnit & transUnit );
     37void fixUniqueIds( ast::TranslationUnit & transUnit );
    3538
    3639/// Expand all traits in an assertion list.
  • src/Validate/GenericParameter.cpp

    r92355883 r2a301ff  
    1616#include "GenericParameter.hpp"
    1717
    18 #include "AST/Copy.hpp"
    1918#include "AST/Decl.hpp"
    2019#include "AST/Expr.hpp"
     
    165164
    166165struct TranslateDimensionCore :
    167                 public WithNoIdSymbolTable, public ast::WithGuards {
     166                public WithNoIdSymbolTable, public ast::WithGuards,
     167                public ast::WithVisitorRef<TranslateDimensionCore> {
    168168
    169169        // SUIT: Struct- or Union- InstType
     
    190190
    191191        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
    192195        const ast::Expr * postvisit( const ast::DimensionExpr * expr );
    193196        const ast::Expr * postvisit( const ast::Expr * expr );
     
    195198};
    196199
     200// Declaration of type variable: forall( [N] )  ->  forall( N & | sized( N ) )
    197201const ast::TypeDecl * TranslateDimensionCore::postvisit(
    198202                const ast::TypeDecl * decl ) {
     
    206210        }
    207211        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;
    208232}
    209233
  • src/Validate/LinkReferenceToTypes.cpp

    r92355883 r2a301ff  
    1010// Created On       : Thr Apr 21 11:41:00 2022
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Sep 20 16:17:00 2022
    13 // Update Count     : 2
     12// Last Modified On : Fri Jul 14  9:19:00 2023
     13// Update Count     : 3
    1414//
    1515
     
    2727struct LinkTypesCore : public WithNoIdSymbolTable,
    2828                public ast::WithCodeLocation,
     29                public ast::WithDeclsToAdd<>,
    2930                public ast::WithGuards,
    3031                public ast::WithShortCircuiting,
     
    6364        template<typename AggrDecl>
    6465        AggrDecl const * renameGenericParams( AggrDecl const * decl );
     66
     67        // This cluster is used to add declarations (before) but outside of
     68        // any "namespaces" which would qualify the names.
     69        bool inNamespace = false;
     70        std::list<ast::ptr<ast::Decl>> declsToAddOutside;
     71        /// The "leaveNamespace" is handled by guard.
     72        void enterNamespace();
     73        /// Puts the decl on the back of declsToAddAfter once traversal is
     74        /// outside of any namespaces.
     75        void addDeclAfterOutside( ast::Decl const * );
    6576};
     77
     78void LinkTypesCore::enterNamespace() {
     79        if ( inNamespace ) return;
     80        inNamespace = true;
     81        GuardAction( [this](){
     82                inNamespace = false;
     83                declsToAddAfter.splice( declsToAddAfter.begin(), declsToAddOutside );
     84        } );
     85}
     86
     87void LinkTypesCore::addDeclAfterOutside( ast::Decl const * decl ) {
     88        if ( inNamespace ) {
     89                declsToAddOutside.emplace_back( decl );
     90        } else {
     91                declsToAddAfter.emplace_back( decl );
     92        }
     93}
    6694
    6795ast::TypeInstType const * LinkTypesCore::postvisit( ast::TypeInstType const * type ) {
     
    81109        ast::EnumDecl const * decl = symtab.lookupEnum( type->name );
    82110        // It's not a semantic error if the enum is not found, just an implicit forward declaration.
    83         if ( decl ) {
    84                 // Just linking in the node.
    85                 auto mut = ast::mutate( type );
    86                 mut->base = decl;
    87                 type = mut;
    88         }
    89         if ( !decl || !decl->body ) {
    90                 auto mut = ast::mutate( type );
     111        // The unset code location is used to detect imaginary declarations.
     112        // (They may never be used for enumerations.)
     113        if ( !decl || decl->location.isUnset() ) {
     114                assert( location );
     115                ast::EnumDecl * mut = new ast::EnumDecl( *location, type->name );
     116                mut->linkage = ast::Linkage::Compiler;
     117                decl = mut;
     118                symtab.addEnum( decl );
     119                addDeclAfterOutside( decl );
     120        }
     121
     122        ast::EnumInstType * mut = ast::mutate( type );
     123
     124        // Just linking in the node.
     125        mut->base = decl;
     126
     127        if ( !decl->body ) {
    91128                forwardEnums[ mut->name ].push_back( mut );
    92                 type = mut;
    93         }
    94         return type;
     129        }
     130        return mut;
    95131}
    96132
     
    98134        ast::StructDecl const * decl = symtab.lookupStruct( type->name );
    99135        // It's not a semantic error if the struct is not found, just an implicit forward declaration.
    100         if ( decl ) {
    101                 // Just linking in the node.
    102                 auto mut = ast::mutate( type );
    103                 mut->base = decl;
    104                 type = mut;
    105         }
    106         if ( !decl || !decl->body ) {
    107                 auto mut = ast::mutate( type );
     136        // The unset code location is used to detect imaginary declarations.
     137        if ( !decl || decl->location.isUnset() ) {
     138                assert( location );
     139                ast::StructDecl * mut = new ast::StructDecl( *location, type->name );
     140                mut->linkage = ast::Linkage::Compiler;
     141                decl = mut;
     142                symtab.addStruct( decl );
     143                addDeclAfterOutside( decl );
     144        }
     145
     146        ast::StructInstType * mut = ast::mutate( type );
     147
     148        // Just linking in the node.
     149        mut->base = decl;
     150
     151        if ( !decl->body ) {
    108152                forwardStructs[ mut->name ].push_back( mut );
    109                 type = mut;
    110         }
    111         return type;
     153        }
     154        return mut;
    112155}
    113156
     
    115158        ast::UnionDecl const * decl = symtab.lookupUnion( type->name );
    116159        // It's not a semantic error if the union is not found, just an implicit forward declaration.
    117         if ( decl ) {
    118                 // Just linking in the node.
    119                 auto mut = ast::mutate( type );
    120                 mut->base = decl;
    121                 type = mut;
    122         }
    123         if ( !decl || !decl->body ) {
    124                 auto mut = ast::mutate( type );
     160        // The unset code location is used to detect imaginary declarations.
     161        if ( !decl || decl->location.isUnset() ) {
     162                assert( location );
     163                ast::UnionDecl * mut = new ast::UnionDecl( *location, type->name );
     164                mut->linkage = ast::Linkage::Compiler;
     165                decl = mut;
     166                symtab.addUnion( decl );
     167                addDeclAfterOutside( decl );
     168        }
     169
     170        ast::UnionInstType * mut = ast::mutate( type );
     171
     172        // Just linking in the node.
     173        mut->base = decl;
     174
     175        if ( !decl->body ) {
    125176                forwardUnions[ mut->name ].push_back( mut );
    126                 type = mut;
    127         }
    128         return type;
     177        }
     178        return mut;
    129179}
    130180
     
    228278
    229279ast::StructDecl const * LinkTypesCore::previsit( ast::StructDecl const * decl ) {
     280        enterNamespace();
    230281        return renameGenericParams( decl );
    231282}
     
    246297
    247298ast::UnionDecl const * LinkTypesCore::previsit( ast::UnionDecl const * decl ) {
     299        enterNamespace();
    248300        return renameGenericParams( decl );
    249301}
     
    264316
    265317ast::TraitDecl const * LinkTypesCore::postvisit( ast::TraitDecl const * decl ) {
    266         auto mut = ast::mutate( decl );
    267         if ( mut->name == "sized" ) {
    268                 // "sized" is a special trait - flick the sized status on for the type variable.
    269                 assertf( mut->params.size() == 1, "Built-in trait 'sized' has incorrect number of parameters: %zd", decl->params.size() );
    270                 ast::TypeDecl * td = mut->params.front().get_and_mutate();
    271                 td->sized = true;
    272         }
    273 
    274318        // There is some overlap with code from decayForallPointers,
    275319        // perhaps reorganization or shared helper functions are called for.
    276320        // Move assertions from type parameters into the body of the trait.
     321        auto mut = ast::mutate( decl );
    277322        for ( ast::ptr<ast::TypeDecl> const & td : decl->params ) {
    278323                auto expanded = expandAssertions( td->assertions );
  • src/Validate/NoIdSymbolTable.hpp

    r92355883 r2a301ff  
    4646        FORWARD_1( addUnion , const ast::UnionDecl *     )
    4747        FORWARD_1( addTrait , const ast::TraitDecl *     )
    48         FORWARD_1( addStruct, const std::string &        )
    49         FORWARD_1( addUnion , const std::string &        )
    5048        FORWARD_2( addWith  , const std::vector< ast::ptr<ast::Expr> > &, const ast::Decl * )
     49        FORWARD_1( addStructId, const std::string & )
     50        FORWARD_1( addUnionId , const std::string & )
    5151
    5252        FORWARD_1( globalLookupType, const std::string & )
  • src/Validate/ReplaceTypedef.cpp

    r92355883 r2a301ff  
    2020#include "Common/ScopedMap.h"
    2121#include "Common/UniqueName.h"
    22 #include "Common/utility.h"
    2322#include "ResolvExpr/Unify.h"
    2423
     
    294293                aggrDecl->name, ast::Storage::Classes(), type, aggrDecl->linkage );
    295294        // Add the implicit typedef to the AST.
    296         declsToAddBefore.push_back( ast::deepCopy( typeDecl.get() ) );
     295        declsToAddAfter.push_back( ast::deepCopy( typeDecl.get() ) );
    297296        // Shore the name in the map of names.
    298297        typedefNames[ aggrDecl->name ] =
     
    316315        auto mut = ast::mutate( decl );
    317316
    318         std::vector<ast::ptr<ast::Decl>> members;
     317        std::list<ast::ptr<ast::Decl>> members;
    319318        // Unroll accept_all for decl->members so that implicit typedefs for
    320319        // nested types are added to the aggregate body.
    321320        for ( ast::ptr<ast::Decl> const & member : mut->members ) {
     321                assert( declsToAddBefore.empty() );
    322322                assert( declsToAddAfter.empty() );
    323323                ast::Decl const * newMember = nullptr;
     
    328328                }
    329329                if ( !declsToAddBefore.empty() ) {
    330                         for ( auto declToAdd : declsToAddBefore ) {
    331                                 members.push_back( declToAdd );
    332                         }
    333                         declsToAddBefore.clear();
     330                        members.splice( members.end(), declsToAddBefore );
    334331                }
    335332                members.push_back( newMember );
    336         }
     333                if ( !declsToAddAfter.empty() ) {
     334                        members.splice( members.end(), declsToAddAfter );
     335                }
     336        }
     337        assert( declsToAddBefore.empty() );
    337338        assert( declsToAddAfter.empty() );
    338339        if ( !errors.isEmpty() ) { throw errors; }
Note: See TracChangeset for help on using the changeset viewer.