Changeset dbf5e18 for src/Validate


Ignore:
Timestamp:
Jul 17, 2023, 9:24:46 AM (2 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
7ed01be
Parents:
847ab8f (diff), 0d7fc00 (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:
3 edited

Legend:

Unmodified
Added
Removed
  • src/Validate/ForallPointerDecay.cpp

    r847ab8f rdbf5e18  
    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(), " is not "
     217                        "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 );
    237239        ast::Pass<UniqueFixCore>::run( transUnit );
    238240}
  • src/Validate/LinkReferenceToTypes.cpp

    r847ab8f rdbf5e18  
    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 ) {
     
    80108ast::EnumInstType const * LinkTypesCore::postvisit( ast::EnumInstType const * type ) {
    81109        ast::EnumDecl const * decl = symtab.lookupEnum( type->name );
     110        // It's not a semantic error if the enum is not found, just an implicit forward declaration.
     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
    82122        ast::EnumInstType * mut = ast::mutate( type );
    83         // It's not a semantic error if the enum is not found, just an implicit forward declaration.
    84         if ( decl ) {
    85                 // Just linking in the node.
    86                 mut->base = decl;
    87         }
    88         if ( !decl || !decl->body ) {
     123
     124        // Just linking in the node.
     125        mut->base = decl;
     126
     127        if ( !decl->body ) {
    89128                forwardEnums[ mut->name ].push_back( mut );
    90129        }
     
    94133ast::StructInstType const * LinkTypesCore::postvisit( ast::StructInstType const * type ) {
    95134        ast::StructDecl const * decl = symtab.lookupStruct( type->name );
     135        // It's not a semantic error if the struct is not found, just an implicit forward declaration.
     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
    96146        ast::StructInstType * mut = ast::mutate( type );
    97         // It's not a semantic error if the struct is not found, just an implicit forward declaration.
    98         if ( decl ) {
    99                 // Just linking in the node.
    100                 mut->base = decl;
    101         }
    102         if ( !decl || !decl->body ) {
     147
     148        // Just linking in the node.
     149        mut->base = decl;
     150
     151        if ( !decl->body ) {
    103152                forwardStructs[ mut->name ].push_back( mut );
    104153        }
     
    108157ast::UnionInstType const * LinkTypesCore::postvisit( ast::UnionInstType const * type ) {
    109158        ast::UnionDecl const * decl = symtab.lookupUnion( type->name );
     159        // It's not a semantic error if the union is not found, just an implicit forward declaration.
     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
    110170        ast::UnionInstType * mut = ast::mutate( type );
    111         // It's not a semantic error if the union is not found, just an implicit forward declaration.
    112         if ( decl ) {
    113                 // Just linking in the node.
    114                 mut->base = decl;
    115         }
    116         if ( !decl || !decl->body ) {
     171
     172        // Just linking in the node.
     173        mut->base = decl;
     174
     175        if ( !decl->body ) {
    117176                forwardUnions[ mut->name ].push_back( mut );
    118177        }
     
    219278
    220279ast::StructDecl const * LinkTypesCore::previsit( ast::StructDecl const * decl ) {
     280        enterNamespace();
    221281        return renameGenericParams( decl );
    222282}
     
    237297
    238298ast::UnionDecl const * LinkTypesCore::previsit( ast::UnionDecl const * decl ) {
     299        enterNamespace();
    239300        return renameGenericParams( decl );
    240301}
  • src/Validate/ReplaceTypedef.cpp

    r847ab8f rdbf5e18  
    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.