Changeset dbf5e18


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
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Util.cpp

    r847ab8f rdbf5e18  
    102102}
    103103
     104/// Check for Floating Nodes:
     105/// Every node should be reachable from a root (the TranslationUnit) via a
     106/// chain of structural references (tracked with ptr). This cannot check all
     107/// of that, it just checks if a given node's field has a strong reference.
     108template<typename node_t, typename field_t>
     109void noFloatingNode( const node_t * node, field_t node_t::*field_ptr ) {
     110        const field_t & field = node->*field_ptr;
     111        if ( nullptr == field ) return;
     112        assertf( field->isManaged(), "Floating node found." );
     113}
     114
    104115struct InvariantCore {
    105116        // To save on the number of visits: this is a kind of composed core.
     
    127138        }
    128139
     140        void previsit( const VariableExpr * node ) {
     141                previsit( (const ParseNode *)node );
     142                noFloatingNode( node, &VariableExpr::var );
     143        }
     144
    129145        void previsit( const MemberExpr * node ) {
    130146                previsit( (const ParseNode *)node );
    131147                memberMatchesAggregate( node );
     148        }
     149
     150        void previsit( const StructInstType * node ) {
     151                previsit( (const Node *)node );
     152                noFloatingNode( node, &StructInstType::base );
     153        }
     154
     155        void previsit( const UnionInstType * node ) {
     156                previsit( (const Node *)node );
     157                noFloatingNode( node, &UnionInstType::base );
     158        }
     159
     160        void previsit( const EnumInstType * node ) {
     161                previsit( (const Node *)node );
     162                noFloatingNode( node, &EnumInstType::base );
     163        }
     164
     165        void previsit( const TypeInstType * node ) {
     166                previsit( (const Node *)node );
     167                noFloatingNode( node, &TypeInstType::base );
    132168        }
    133169
  • src/InitTweak/InitTweak.cc

    r847ab8f rdbf5e18  
    882882                if (!assign) {
    883883                        auto td = new ast::TypeDecl(CodeLocation(), "T", {}, nullptr, ast::TypeDecl::Dtype, true);
    884                         assign = new ast::FunctionDecl(CodeLocation(), "?=?", {},
     884                        assign = new ast::FunctionDecl(CodeLocation(), "?=?", {td},
    885885                        { new ast::ObjectDecl(CodeLocation(), "_dst", new ast::ReferenceType(new ast::TypeInstType("T", td))),
    886886                          new ast::ObjectDecl(CodeLocation(), "_src", new ast::TypeInstType("T", td))},
  • src/Parser/parser.yy

    r847ab8f rdbf5e18  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 12 06:14:16 2023
    13 // Update Count     : 6382
     12// Last Modified On : Wed Jul 12 23:06:44 2023
     13// Update Count     : 6389
    1414//
    1515
     
    18681868
    18691869KR_parameter_list:
    1870         push c_declaration pop ';'
    1871                 { $$ = $2; }
    1872         | KR_parameter_list push c_declaration pop ';'
    1873                 { $$ = $1->appendList( $3 ); }
     1870        c_declaration ';'
     1871                { $$ = $1; }
     1872        | KR_parameter_list c_declaration ';'
     1873                { $$ = $1->appendList( $2 ); }
    18741874        ;
    18751875
     
    20332033                        } else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3
    20342034                }
    2035         | typedef_declaration pop ',' push declarator
    2036                 {
    2037                         typedefTable.addToEnclosingScope( *$5->name, TYPEDEFname, "typedef_declaration 2" );
    2038                         $$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() );
     2035        | typedef_declaration ',' declarator
     2036                {
     2037                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "typedef_declaration 2" );
     2038                        $$ = $1->appendList( $1->cloneBaseType( $3 )->addTypedef() );
    20392039                }
    20402040        | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 )
     
    20522052                        SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    20532053                }
    2054         | typedef_expression pop ',' push identifier '=' assignment_expression
     2054        | typedef_expression ',' identifier '=' assignment_expression
    20552055                {
    20562056                        SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
  • 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.