Changeset 223a633 for src


Ignore:
Timestamp:
Oct 15, 2020, 3:41:38 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
b9537e6
Parents:
33c3ded (diff), 0b18db7 (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:
31 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r33c3ded r223a633  
    177177        const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
    178178                if ( inCache( node ) ) return nullptr;
     179
     180                // function decl contains real variables that the type must use.
     181                // the structural change means function type in and out of decl
     182                // must be handled **differently** on convert back to old.
     183                auto ftype = new FunctionType(
     184                        cv(node->type),
     185                        (bool)node->type->isVarArgs
     186                );
     187                ftype->returnVals = get<DeclarationWithType>().acceptL(node->returns);
     188                ftype->parameters = get<DeclarationWithType>().acceptL(node->params);
     189
     190                ftype->forall = get<TypeDecl>().acceptL( node->type->forall );
     191
     192                visitType(node->type, ftype);
     193
    179194                auto decl = new FunctionDecl(
    180195                        node->name,
    181196                        Type::StorageClasses( node->storage.val ),
    182197                        LinkageSpec::Spec( node->linkage.val ),
    183                         get<FunctionType>().accept1( node->type ),
     198                        ftype,
     199                        //get<FunctionType>().accept1( node->type ),
    184200                        {},
    185201                        get<Attribute>().acceptL( node->attributes ),
     
    11521168
    11531169        const ast::Type * visit( const ast::FunctionType * node ) override final {
     1170                static std::string dummy_paramvar_prefix = "__param_";
     1171                static std::string dummy_returnvar_prefix = "__retval_";
     1172
    11541173                auto ty = new FunctionType {
    11551174                        cv( node ),
    11561175                        (bool)node->isVarArgs
    11571176                };
    1158                 ty->returnVals = get<DeclarationWithType>().acceptL( node->returns );
    1159                 ty->parameters = get<DeclarationWithType>().acceptL( node->params );
     1177                auto returns = get<Type>().acceptL(node->returns);
     1178                auto params = get<Type>().acceptL(node->params);
     1179
     1180                int ret_index = 0;
     1181                for (auto t: returns) {
     1182                        // xxx - LinkageSpec shouldn't matter but needs to be something
     1183                        ObjectDecl * dummy = new ObjectDecl(dummy_returnvar_prefix + std::to_string(ret_index++), {}, LinkageSpec::C, nullptr, t, nullptr);
     1184                        ty->returnVals.push_back(dummy);
     1185                }
     1186                int param_index = 0;
     1187                for (auto t: params) {
     1188                        ObjectDecl * dummy = new ObjectDecl(dummy_paramvar_prefix + std::to_string(param_index++), {}, LinkageSpec::C, nullptr, t, nullptr);
     1189                        ty->parameters.push_back(dummy);
     1190                }
     1191
     1192                // ty->returnVals = get<DeclarationWithType>().acceptL( node->returns );
     1193                // ty->parameters = get<DeclarationWithType>().acceptL( node->params );
    11601194                ty->forall = get<TypeDecl>().acceptL( node->forall );
    11611195                return visitType( node, ty );
     
    13741408        ast::Node * node = nullptr;
    13751409        /// cache of nodes that might be referenced by readonly<> for de-duplication
    1376         std::unordered_map< const BaseSyntaxNode *, ast::Node * > cache = {};
     1410        /// in case that some nodes are dropped by conversion (due to possible structural change)
     1411        /// use smart pointers in cache value to prevent accidental invalidation.
     1412        /// at conversion stage, all created nodes are guaranteed to be unique, therefore
     1413        /// const_casting out of smart pointers is permitted.
     1414        std::unordered_map< const BaseSyntaxNode *, ast::ptr<ast::Node> > cache = {};
    13771415
    13781416        // Local Utilities:
     
    14471485                auto it = cache.find( old );
    14481486                if ( it == cache.end() ) return false;
    1449                 node = it->second;
     1487                node = const_cast<ast::Node *>(it->second.get());
    14501488                return true;
    14511489        }
     
    14861524        virtual void visit( const FunctionDecl * old ) override final {
    14871525                if ( inCache( old ) ) return;
     1526                auto paramVars = GET_ACCEPT_V(type->parameters, DeclWithType);
     1527                auto returnVars = GET_ACCEPT_V(type->returnVals, DeclWithType);
     1528                auto forall = GET_ACCEPT_V(type->forall, TypeDecl);
     1529
     1530                // function type is now derived from parameter decls instead of storing them
     1531                auto ftype = new ast::FunctionType((ast::ArgumentFlag)old->type->isVarArgs, cv(old->type));
     1532                ftype->params.reserve(paramVars.size());
     1533                ftype->returns.reserve(returnVars.size());
     1534
     1535                for (auto & v: paramVars) {
     1536                        ftype->params.emplace_back(v->get_type());
     1537                }
     1538                for (auto & v: returnVars) {
     1539                        ftype->returns.emplace_back(v->get_type());
     1540                }
     1541                ftype->forall = std::move(forall);
     1542                visitType(old->type, ftype);
     1543
    14881544                auto decl = new ast::FunctionDecl{
    14891545                        old->location,
    14901546                        old->name,
    1491                         GET_ACCEPT_1(type, FunctionType),
     1547                        // GET_ACCEPT_1(type, FunctionType),
     1548                        std::move(paramVars),
     1549                        std::move(returnVars),
    14921550                        {},
    14931551                        { old->storageClasses.val },
     
    14961554                        { old->get_funcSpec().val }
    14971555                };
     1556
     1557                decl->type = ftype;
    14981558                cache.emplace( old, decl );
     1559
    14991560                decl->withExprs = GET_ACCEPT_V(withExprs, Expr);
    15001561                decl->stmts = GET_ACCEPT_1(statements, CompoundStmt);
     
    25152576                        cv( old )
    25162577                };
    2517                 ty->returns = GET_ACCEPT_V( returnVals, DeclWithType );
    2518                 ty->params = GET_ACCEPT_V( parameters, DeclWithType );
     2578                auto returnVars = GET_ACCEPT_V(returnVals, DeclWithType);
     2579                auto paramVars = GET_ACCEPT_V(parameters, DeclWithType);
     2580                // ty->returns = GET_ACCEPT_V( returnVals, DeclWithType );
     2581                // ty->params = GET_ACCEPT_V( parameters, DeclWithType );
     2582                for (auto & v: returnVars) {
     2583                        ty->returns.emplace_back(v->get_type());
     2584                }
     2585                for (auto & v: paramVars) {
     2586                        ty->params.emplace_back(v->get_type());
     2587                }
    25192588                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
    25202589                visitType( old, ty );
  • src/AST/Decl.hpp

    r33c3ded r223a633  
    124124class FunctionDecl : public DeclWithType {
    125125public:
     126        std::vector<ptr<DeclWithType>> params;
     127        std::vector<ptr<DeclWithType>> returns;
     128        // declared type, derived from parameter declarations
    126129        ptr<FunctionType> type;
    127130        ptr<CompoundStmt> stmts;
    128131        std::vector< ptr<Expr> > withExprs;
    129132
    130         FunctionDecl( const CodeLocation & loc, const std::string & name, FunctionType * type,
     133        FunctionDecl( const CodeLocation & loc, const std::string & name,
     134                std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
    131135                CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C,
    132136                std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {})
    133         : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ),
     137        : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)),
    134138          stmts( stmts ) {}
    135139
  • src/AST/ForallSubstitutor.hpp

    r33c3ded r223a633  
    3333        }
    3434
     35        template<typename node_t >
     36        std::vector<ptr<node_t>> operator() (const std::vector<ptr<node_t>> & o) {
     37                std::vector<ptr<node_t>> n;
     38                n.reserve(o.size());
     39                for (const node_t * d : o) { n.emplace_back(d->accept(*visitor)); }
     40                return n;
     41        }
     42       
     43        /*
     44
    3545        /// Substitute parameter/return type
    3646        std::vector< ptr< DeclWithType > > operator() ( const std::vector< ptr< DeclWithType > > & o ) {
     
    4858                return n;
    4959        }
     60
     61        */
    5062};
    5163
  • src/AST/Pass.impl.hpp

    r33c3ded r223a633  
    465465                        __pass::symtab::addId( core, 0, func );
    466466                        VISIT(
     467                                // parameter declarations are now directly here
     468                                maybe_accept( node, &FunctionDecl::params );
     469                                maybe_accept( node, &FunctionDecl::returns );
     470                                // foralls are still in function type
    467471                                maybe_accept( node, &FunctionDecl::type );
    468472                                // function body needs to have the same scope as parameters - CompoundStmt will not enter
  • src/AST/SymbolTable.cpp

    r33c3ded r223a633  
    335335}
    336336
     337/*
    337338void SymbolTable::addFunctionType( const FunctionType * ftype ) {
    338339        addTypes( ftype->forall );
     
    340341        addIds( ftype->params );
    341342}
     343*/
    342344
    343345void SymbolTable::lazyInitScope() {
     
    368370                assert( ! params.empty() );
    369371                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
    370                 const Type * base = InitTweak::getPointerBase( params.front()->get_type() );
     372                const Type * base = InitTweak::getPointerBase( params.front() );
    371373                assert( base );
    372374                return Mangle::mangle( base );
  • src/AST/SymbolTable.hpp

    r33c3ded r223a633  
    145145
    146146        /// convenience function for adding all of the declarations in a function type to the indexer
    147         void addFunctionType( const FunctionType * ftype );
     147        // void addFunctionType( const FunctionType * ftype );
    148148
    149149private:
  • src/AST/Type.cpp

    r33c3ded r223a633  
    102102// --- FunctionType
    103103
     104
    104105FunctionType::FunctionType( const FunctionType & o )
    105106: ParameterizedType( o.qualifiers, copy( o.attributes ) ), returns(), params(),
     
    112113
    113114namespace {
    114         bool containsTtype( const std::vector<ptr<DeclWithType>> & l ) {
     115        bool containsTtype( const std::vector<ptr<Type>> & l ) {
    115116                if ( ! l.empty() ) {
    116                         return Tuples::isTtype( l.back()->get_type() );
     117                        return Tuples::isTtype( l.back() );
    117118                }
    118119                return false;
  • src/AST/Type.hpp

    r33c3ded r223a633  
    302302class FunctionType final : public ParameterizedType {
    303303public:
    304         std::vector<ptr<DeclWithType>> returns;
    305         std::vector<ptr<DeclWithType>> params;
     304//      std::vector<ptr<DeclWithType>> returns;
     305//      std::vector<ptr<DeclWithType>> params;
     306
     307        std::vector<ptr<Type>> returns;
     308        std::vector<ptr<Type>> params;
    306309
    307310        /// Does the function accept a variable number of arguments following the arguments specified
  • src/Concurrency/Keywords.cc

    r33c3ded r223a633  
    6666                        bool needs_main, AggregateDecl::Aggregate cast_target ) :
    6767                  type_name( type_name ), field_name( field_name ), getter_name( getter_name ),
    68                   context_error( context_error ), vtable_name( getVTableName( exception_name ) ),
     68                  context_error( context_error ), exception_name( exception_name ),
     69                  vtable_name( getVTableName( exception_name ) ),
    6970                  needs_main( needs_main ), cast_target( cast_target ) {}
    7071
     
    8990                const std::string getter_name;
    9091                const std::string context_error;
     92                const std::string exception_name;
    9193                const std::string vtable_name;
    9294                bool needs_main;
     
    9597                StructDecl   * type_decl = nullptr;
    9698                FunctionDecl * dtor_decl = nullptr;
     99                StructDecl * except_decl = nullptr;
    97100                StructDecl * vtable_decl = nullptr;
    98101        };
     
    376379                else if ( is_target(decl) ) {
    377380                        handle( decl );
     381                }
     382                else if ( !except_decl && exception_name == decl->name && decl->body ) {
     383                        except_decl = decl;
    378384                }
    379385                else if ( !vtable_decl && vtable_name == decl->name && decl->body ) {
     
    398404                        assert( struct_type );
    399405
    400                         declsToAddAfter.push_back( Virtual::makeVtableInstance( vtable_decl, {
    401                                 new TypeExpr( struct_type->clone() ),
    402                         }, struct_type, nullptr ) );
     406                        std::list< Expression * > poly_args = { new TypeExpr( struct_type->clone() ) };
     407                        ObjectDecl * vtable_object = Virtual::makeVtableInstance(
     408                                vtable_decl->makeInst( poly_args ), struct_type, nullptr );
     409                        declsToAddAfter.push_back( vtable_object );
     410                        declsToAddAfter.push_back( Virtual::makeGetExceptionFunction(
     411                                vtable_object, except_decl->makeInst( std::move( poly_args ) )
     412                        ) );
    403413                }
    404414
     
    434444        void ConcurrentSueKeyword::addVtableForward( StructDecl * decl ) {
    435445                if ( vtable_decl ) {
    436                         declsToAddBefore.push_back( Virtual::makeVtableForward( vtable_decl, {
     446                        std::list< Expression * > poly_args = {
    437447                                new TypeExpr( new StructInstType( noQualifiers, decl ) ),
    438                         } ) );
     448                        };
     449                        declsToAddBefore.push_back( Virtual::makeGetExceptionForward(
     450                                vtable_decl->makeInst( poly_args ),
     451                                except_decl->makeInst( poly_args )
     452                        ) );
     453                        declsToAddBefore.push_back( Virtual::makeVtableForward(
     454                                vtable_decl->makeInst( move( poly_args ) ) ) );
    439455                // Its only an error if we want a vtable and don't have one.
    440456                } else if ( ! vtable_name.empty() ) {
  • src/GenPoly/InstantiateGeneric.cc

    r33c3ded r223a633  
    172172                InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
    173173                /// Set of types which are dtype-only generic (and therefore have static layout)
    174                 ScopedSet< AggregateDecl* > dtypeStatics;
     174                std::set<AggregateDecl *> dtypeStatics;
    175175                /// Namer for concrete types
    176176                UniqueName typeNamer;
     
    505505        void GenericInstantiator::beginScope() {
    506506                instantiations.beginScope();
    507                 dtypeStatics.beginScope();
    508507        }
    509508
    510509        void GenericInstantiator::endScope() {
    511510                instantiations.endScope();
    512                 dtypeStatics.endScope();
    513511        }
    514512
  • src/InitTweak/FixGlobalInit.cc

    r33c3ded r223a633  
    112112                        } // if
    113113                        if ( Statement * ctor = ctorInit->ctor ) {
     114                                // Translation 1: Add this attribute on the global declaration:
     115                                //    __attribute__((section (".data#")))
     116                                // which makes gcc put the global in the data section,
     117                                // so that the global is writeable (via a const cast) in the init function.
     118                                // The trailing # is an injected assembly comment, to suppress the "a" in
     119                                //    .section .data,"a"
     120                                //    .section .data#,"a"
     121                                // to avoid assembler warning "ignoring changed section attributes for .data"
     122                                Type *strLitT = new PointerType( Type::Qualifiers( ),
     123                                        new BasicType( Type::Qualifiers( ), BasicType::Char ) );
     124                                std::list< Expression * > attr_params;
     125                                attr_params.push_back(
     126                                        new ConstantExpr( Constant( strLitT, "\".data#\"", std::nullopt ) ) );
     127                                objDecl->attributes.push_back(new Attribute("section", attr_params));
     128                                // Translation 2: Move the initizliation off the global declaration,
     129                                // into the startup function.
    114130                                initStatements.push_back( ctor );
    115131                                objDecl->init = nullptr;
  • src/InitTweak/InitTweak.cc

    r33c3ded r223a633  
    10261026                if ( ftype->params.size() != 2 ) return false;
    10271027
    1028                 const ast::Type * t1 = getPointerBase( ftype->params.front()->get_type() );
     1028                const ast::Type * t1 = getPointerBase( ftype->params.front() );
    10291029                if ( ! t1 ) return false;
    1030                 const ast::Type * t2 = ftype->params.back()->get_type();
     1030                const ast::Type * t2 = ftype->params.back();
    10311031
    10321032                return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} );
  • src/Parser/DeclarationNode.cc

    r33c3ded r223a633  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jun  9 20:26:55 2020
    13 // Update Count     : 1134
     12// Last Modified On : Thu Oct  8 08:03:38 2020
     13// Update Count     : 1135
    1414//
    1515
     
    10161016                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
    10171017                                dwt->location = cur->location;
    1018                                 * out++ = dwt;
     1018                                *out++ = dwt;
    10191019                        } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
    10201020                                // e.g., int foo(struct S) {}
     
    10221022                                auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    10231023                                obj->location = cur->location;
    1024                                 * out++ = obj;
     1024                                *out++ = obj;
    10251025                                delete agg;
    10261026                        } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
     
    10291029                                auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    10301030                                obj->location = cur->location;
    1031                                 * out++ = obj;
     1031                                *out++ = obj;
    10321032                        } else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) {
    10331033                                // e.g., int foo(enum E) {}
     
    10351035                                auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    10361036                                obj->location = cur->location;
    1037                                 * out++ = obj;
     1037                                *out++ = obj;
    10381038                        } // if
    10391039                } catch( SemanticErrorException & e ) {
  • src/Parser/lex.ll

    r33c3ded r223a633  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Sat Feb 15 11:05:50 2020
    13  * Update Count     : 737
     12 * Last Modified On : Tue Oct  6 18:15:41 2020
     13 * Update Count     : 743
    1414 */
    1515
     
    6262#define IDENTIFIER_RETURN()     RETURN_VAL( typedefTable.isKind( yytext ) )
    6363
    64 #ifdef HAVE_KEYWORDS_FLOATXX                                                            // GCC >= 7 => keyword, otherwise typedef
     64#ifdef HAVE_KEYWORDS_FLOATXX                                                    // GCC >= 7 => keyword, otherwise typedef
    6565#define FLOATXX(v) KEYWORD_RETURN(v);
    6666#else
     
    292292__restrict__    { KEYWORD_RETURN(RESTRICT); }                   // GCC
    293293return                  { KEYWORD_RETURN(RETURN); }
    294         /* resume                       { KEYWORD_RETURN(RESUME); }                             // CFA */
     294 /* resume                      { KEYWORD_RETURN(RESUME); }                             // CFA */
    295295short                   { KEYWORD_RETURN(SHORT); }
    296296signed                  { KEYWORD_RETURN(SIGNED); }
  • src/Parser/parser.yy

    r33c3ded r223a633  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu May 28 12:11:45 2020
    13 // Update Count     : 4500
     12// Last Modified On : Fri Oct  9 18:09:09 2020
     13// Update Count     : 4614
    1414//
    1515
     
    204204                        return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
    205205                } else {
    206                         SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); return nullptr;
     206                        SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr;
    207207                } // if
    208208        } else {
    209                 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); return nullptr;
     209                SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr;
    210210        } // if
    211211} // forCtrl
     
    278278%token OTYPE FTYPE DTYPE TTYPE TRAIT                                    // CFA
    279279%token SIZEOF OFFSETOF
    280 // %token RESUME                                                                        // CFA
    281 %token SUSPEND                                                                  // CFA
     280// %token RESUME                                                                                        // CFA
     281%token SUSPEND                                                                                  // CFA
    282282%token ATTRIBUTE EXTENSION                                                              // GCC
    283283%token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN
     
    329329%type<en> conditional_expression                constant_expression                     assignment_expression           assignment_expression_opt
    330330%type<en> comma_expression                              comma_expression_opt
    331 %type<en> argument_expression_list_opt          argument_expression                     default_initialize_opt
     331%type<en> argument_expression_list_opt  argument_expression                     default_initialize_opt
    332332%type<ifctl> if_control_expression
    333333%type<fctl> for_control_expression              for_control_expression_list
     
    370370%type<decl> assertion assertion_list assertion_list_opt
    371371
    372 %type<en>   bit_subrange_size_opt bit_subrange_size
     372%type<en> bit_subrange_size_opt bit_subrange_size
    373373
    374374%type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type
     
    793793        | '(' aggregate_control '&' ')' cast_expression         // CFA
    794794                { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
    795                 // VIRTUAL cannot be opt because of look ahead issues
    796795        | '(' VIRTUAL ')' cast_expression                                       // CFA
    797796                { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $4 ), maybeMoveBuildType( nullptr ) ) ); }
     
    920919        | unary_expression assignment_operator assignment_expression
    921920                {
    922                         if ( $2 == OperKinds::AtAssn ) {
    923                                 SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr;
    924                         } else {
     921//                      if ( $2 == OperKinds::AtAssn ) {
     922//                              SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr;
     923//                      } else {
    925924                                $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) );
    926                         } // if
     925//                      } // if
    927926                }
    928927        | unary_expression '=' '{' initializer_list_opt comma_opt '}'
     
    16761675
    16771676typedef_expression:
    1678                 // GCC, naming expression type: typedef name = exp; gives a name to the type of an expression
     1677                // deprecated GCC, naming expression type: typedef name = exp; gives a name to the type of an expression
    16791678        TYPEDEF identifier '=' assignment_expression
    16801679                {
    1681                         // $$ = DeclarationNode::newName( 0 );                  // unimplemented
    1682                         SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr;
     1680                        SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    16831681                }
    16841682        | typedef_expression pop ',' push identifier '=' assignment_expression
    16851683                {
    1686                         // $$ = DeclarationNode::newName( 0 );                  // unimplemented
    1687                         SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr;
    1688                 }
    1689         ;
    1690 
    1691 //c_declaration:
    1692 //      declaring_list pop ';'
    1693 //      | typedef_declaration pop ';'
    1694 //      | typedef_expression pop ';'                                            // GCC, naming expression type
    1695 //      | sue_declaration_specifier pop ';'
    1696 //      ;
    1697 //
    1698 //declaring_list:
    1699 //              // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static
    1700 //              // storage-class
    1701 //       declarator asm_name_opt initializer_opt
    1702 //              {
    1703 //                      typedefTable.addToEnclosingScope( IDENTIFIER );
    1704 //                      $$ = ( $2->addType( $1 ))->addAsmName( $3 )->addInitializer( $4 );
    1705 //              }
    1706 //      | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
    1707 //              {
    1708 //                      typedefTable.addToEnclosingScope( IDENTIFIER );
    1709 //                      $$ = $1->appendList( $1->cloneBaseType( $4->addAsmName( $5 )->addInitializer( $6 ) ) );
    1710 //              }
    1711 //      ;
     1684                        SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     1685                }
     1686        ;
    17121687
    17131688c_declaration:
     
    17151690                { $$ = distAttr( $1, $2 ); }
    17161691        | typedef_declaration
    1717         | typedef_expression                                                            // GCC, naming expression type
     1692        | typedef_expression                                                            // deprecated GCC, naming expression type
    17181693        | sue_declaration_specifier
    17191694        ;
     
    20942069                { yyy = true; $$ = AggregateDecl::Union; }
    20952070        | EXCEPTION                                                                                     // CFA
    2096                 { yyy = true; $$ = AggregateDecl::Exception; }
     2071                // { yyy = true; $$ = AggregateDecl::Exception; }
     2072                { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    20972073        ;
    20982074
     
    24362412// Overloading: function, data, and operator identifiers may be overloaded.
    24372413//
    2438 // Type declarations: "type" is used to generate new types for declaring objects. Similarly, "dtype" is used for object
     2414// Type declarations: "otype" is used to generate new types for declaring objects. Similarly, "dtype" is used for object
    24392415//     and incomplete types, and "ftype" is used for function types. Type declarations with initializers provide
    24402416//     definitions of new types. Type declarations with storage class "extern" provide opaque types.
     
    24652441        type_class identifier_or_type_name
    24662442                { typedefTable.addToScope( *$2, TYPEDEFname, "9" ); }
    2467           type_initializer_opt assertion_list_opt
     2443        type_initializer_opt assertion_list_opt
    24682444                { $$ = DeclarationNode::newTypeParam( $1, $2 )->addTypeInitializer( $4 )->addAssertions( $5 ); }
    24692445        | type_specifier identifier_parameter_declarator
     
    24922468        assertion
    24932469        | assertion_list assertion
    2494                 { $$ = $1 ? $1->appendList( $2 ) : $2; }
     2470                { $$ = $1->appendList( $2 ); }
    24952471        ;
    24962472
  • src/ResolvExpr/CandidateFinder.cpp

    r33c3ded r223a633  
    188188
    189189                        // mark conversion cost and also specialization cost of param type
    190                         const ast::Type * paramType = (*param)->get_type();
     190                        // const ast::Type * paramType = (*param)->get_type();
    191191                        cand->expr = ast::mutate_field_index(
    192192                                appExpr, &ast::ApplicationExpr::args, i,
    193193                                computeExpressionConversionCost(
    194                                         args[i], paramType, symtab, cand->env, convCost ) );
    195                         convCost.decSpec( specCost( paramType ) );
     194                                        args[i], *param, symtab, cand->env, convCost ) );
     195                        convCost.decSpec( specCost( *param ) );
    196196                        ++param;  // can't be in for-loop update because of the continue
    197197                }
     
    698698                        if ( targetType && ! targetType->isVoid() && ! funcType->returns.empty() ) {
    699699                                // attempt to narrow based on expected target type
    700                                 const ast::Type * returnType = funcType->returns.front()->get_type();
     700                                const ast::Type * returnType = funcType->returns.front();
    701701                                if ( ! unify(
    702702                                        returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, symtab )
     
    712712                        std::size_t genStart = 0;
    713713
    714                         for ( const ast::DeclWithType * param : funcType->params ) {
    715                                 auto obj = strict_dynamic_cast< const ast::ObjectDecl * >( param );
     714                        // xxx - how to handle default arg after change to ftype representation?
     715                        if (const ast::VariableExpr * varExpr = func->expr.as<ast::VariableExpr>()) {
     716                                if (const ast::FunctionDecl * funcDecl = varExpr->var.as<ast::FunctionDecl>()) {
     717                                        // function may have default args only if directly calling by name
     718                                        // must use types on candidate however, due to RenameVars substitution
     719                                        auto nParams = funcType->params.size();
     720
     721                                        for (size_t i=0; i<nParams; ++i) {
     722                                                auto obj = funcDecl->params[i].strict_as<ast::ObjectDecl>();
     723                                                if (!instantiateArgument(
     724                                                        funcType->params[i], obj->init, args, results, genStart, symtab)) return;
     725                                        }
     726                                        goto endMatch;
     727                                }
     728                        }
     729                        for ( const auto & param : funcType->params ) {
    716730                                // Try adding the arguments corresponding to the current parameter to the existing
    717731                                // matches
     732                                // no default args for indirect calls
    718733                                if ( ! instantiateArgument(
    719                                         obj->type, obj->init, args, results, genStart, symtab ) ) return;
    720                         }
    721 
     734                                        param, nullptr, args, results, genStart, symtab ) ) return;
     735                        }
     736
     737                        endMatch:
    722738                        if ( funcType->isVarArgs ) {
    723739                                // append any unused arguments to vararg pack
  • src/ResolvExpr/CurrentObject.cc

    r33c3ded r223a633  
    594594        class SimpleIterator final : public MemberIterator {
    595595                CodeLocation location;
    596                 readonly< Type > type = nullptr;
     596                const Type * type = nullptr;
    597597        public:
    598598                SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {}
     
    630630        class ArrayIterator final : public MemberIterator {
    631631                CodeLocation location;
    632                 readonly< ArrayType > array = nullptr;
    633                 readonly< Type > base = nullptr;
     632                const ArrayType * array = nullptr;
     633                const Type * base = nullptr;
    634634                size_t index = 0;
    635635                size_t size = 0;
  • src/ResolvExpr/ResolveAssertions.cc

    r33c3ded r223a633  
    277277                        const DeclarationWithType * candidate = cdata.id;
    278278
    279                         // build independent unification context for candidate
     279                        // ignore deleted candidates.
     280                        // NOTE: this behavior is different from main resolver.
     281                        // further investigations might be needed to determine
     282                        // if we should implement the same rule here
     283                        // (i.e. error if unique best match is deleted)
     284                        if (candidate->isDeleted) continue;
     285
     286                        // build independent unification context. for candidate
    280287                        AssertionSet have, newNeed;
    281288                        TypeEnvironment newEnv{ resn.alt.env };
  • src/ResolvExpr/Resolver.cc

    r33c3ded r223a633  
    12231223                template<typename Iter>
    12241224                inline bool nextMutex( Iter & it, const Iter & end ) {
    1225                         while ( it != end && ! (*it)->get_type()->is_mutex() ) { ++it; }
     1225                        while ( it != end && ! (*it)->is_mutex() ) { ++it; }
    12261226                        return it != end;
    12271227                }
     
    16381638                                                                // Check if the argument matches the parameter type in the current
    16391639                                                                // scope
    1640                                                                 ast::ptr< ast::Type > paramType = (*param)->get_type();
     1640                                                                // ast::ptr< ast::Type > paramType = (*param)->get_type();
    16411641                                                                if (
    16421642                                                                        ! unify(
    1643                                                                                 arg->expr->result, paramType, resultEnv, need, have, open,
     1643                                                                                arg->expr->result, *param, resultEnv, need, have, open,
    16441644                                                                                symtab )
    16451645                                                                ) {
     
    16481648                                                                        ss << "candidate function not viable: no known conversion "
    16491649                                                                                "from '";
    1650                                                                         ast::print( ss, (*param)->get_type() );
     1650                                                                        ast::print( ss, *param );
    16511651                                                                        ss << "' to '";
    16521652                                                                        ast::print( ss, arg->expr->result );
  • src/ResolvExpr/SatisfyAssertions.cpp

    r33c3ded r223a633  
    170170                        const ast::DeclWithType * candidate = cdata.id;
    171171
     172                        // ignore deleted candidates.
     173                        // NOTE: this behavior is different from main resolver.
     174                        // further investigations might be needed to determine
     175                        // if we should implement the same rule here
     176                        // (i.e. error if unique best match is deleted)
     177                        if (candidate->isDeleted) continue;
     178
    172179                        // build independent unification context for candidate
    173180                        ast::AssertionSet have, newNeed;
     
    318325                                        if ( ! func ) continue;
    319326
    320                                         for ( const ast::DeclWithType * param : func->params ) {
    321                                                 cost.decSpec( specCost( param->get_type() ) );
     327                                        for ( const auto & param : func->params ) {
     328                                                cost.decSpec( specCost( param ) );
    322329                                        }
    323330
  • src/ResolvExpr/SpecCost.cc

    r33c3ded r223a633  
    178178                void previsit( const ast::FunctionType * fty ) {
    179179                        int minCount = std::numeric_limits<int>::max();
    180                         updateMinimumPresent( minCount, fty->params, decl_type );
    181                         updateMinimumPresent( minCount, fty->returns, decl_type );
     180                        updateMinimumPresent( minCount, fty->params, type_deref );
     181                        updateMinimumPresent( minCount, fty->returns, type_deref );
    182182                        // Add another level to minCount if set.
    183183                        count = toNoneOrInc( minCount );
  • src/ResolvExpr/Unify.cc

    r33c3ded r223a633  
    395395
    396396        template< typename Iterator1, typename Iterator2 >
    397         bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
     397        bool unifyTypeList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    398398                auto get_type = [](DeclarationWithType * dwt){ return dwt->get_type(); };
    399399                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
     
    489489                                        || flatOther->isTtype()
    490490                        ) {
    491                                 if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    492                                         if ( unifyDeclList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     491                                if ( unifyTypeList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     492                                        if ( unifyTypeList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    493493
    494494                                                // the original types must be used in mark assertions, since pointer comparisons are used
     
    784784
    785785                /// returns flattened version of `src`
    786                 static std::vector< ast::ptr< ast::DeclWithType > > flattenList(
    787                         const std::vector< ast::ptr< ast::DeclWithType > > & src, ast::TypeEnvironment & env
     786                static std::vector< ast::ptr< ast::Type > > flattenList(
     787                        const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env
    788788                ) {
    789                         std::vector< ast::ptr< ast::DeclWithType > > dst;
     789                        std::vector< ast::ptr< ast::Type > > dst;
    790790                        dst.reserve( src.size() );
    791                         for ( const ast::DeclWithType * d : src ) {
     791                        for ( const auto & d : src ) {
    792792                                ast::Pass<TtypeExpander_new> expander{ env };
    793793                                // TtypeExpander pass is impure (may mutate nodes in place)
    794794                                // need to make nodes shared to prevent accidental mutation
    795                                 ast::ptr<ast::DeclWithType> dc = d->accept(expander);
    796                                 auto types = flatten( dc->get_type() );
     795                                ast::ptr<ast::Type> dc = d->accept(expander);
     796                                auto types = flatten( dc );
    797797                                for ( ast::ptr< ast::Type > & t : types ) {
    798798                                        // outermost const, volatile, _Atomic qualifiers in parameters should not play
     
    803803                                        // requirements than a non-mutex function
    804804                                        remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic );
    805                                         dst.emplace_back( new ast::ObjectDecl{ dc->location, "", t } );
     805                                        dst.emplace_back( t );
    806806                                }
    807807                        }
     
    811811                /// Creates a tuple type based on a list of DeclWithType
    812812                template< typename Iter >
    813                 static ast::ptr< ast::Type > tupleFromDecls( Iter crnt, Iter end ) {
     813                static ast::ptr< ast::Type > tupleFromTypes( Iter crnt, Iter end ) {
    814814                        std::vector< ast::ptr< ast::Type > > types;
    815815                        while ( crnt != end ) {
    816816                                // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
    817817                                // that this results in a flat tuple
    818                                 flatten( (*crnt)->get_type(), types );
     818                                flatten( *crnt, types );
    819819
    820820                                ++crnt;
     
    825825
    826826                template< typename Iter >
    827                 static bool unifyDeclList(
     827                static bool unifyTypeList(
    828828                        Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env,
    829829                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     
    831831                ) {
    832832                        while ( crnt1 != end1 && crnt2 != end2 ) {
    833                                 const ast::Type * t1 = (*crnt1)->get_type();
    834                                 const ast::Type * t2 = (*crnt2)->get_type();
     833                                const ast::Type * t1 = *crnt1;
     834                                const ast::Type * t2 = *crnt2;
    835835                                bool isTuple1 = Tuples::isTtype( t1 );
    836836                                bool isTuple2 = Tuples::isTtype( t2 );
     
    840840                                        // combine remainder of list2, then unify
    841841                                        return unifyExact(
    842                                                 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
     842                                                t1, tupleFromTypes( crnt2, end2 ), env, need, have, open,
    843843                                                noWiden(), symtab );
    844844                                } else if ( ! isTuple1 && isTuple2 ) {
    845845                                        // combine remainder of list1, then unify
    846846                                        return unifyExact(
    847                                                 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
     847                                                tupleFromTypes( crnt1, end1 ), t2, env, need, have, open,
    848848                                                noWiden(), symtab );
    849849                                }
     
    860860                        if ( crnt1 != end1 ) {
    861861                                // try unifying empty tuple with ttype
    862                                 const ast::Type * t1 = (*crnt1)->get_type();
     862                                const ast::Type * t1 = *crnt1;
    863863                                if ( ! Tuples::isTtype( t1 ) ) return false;
    864864                                return unifyExact(
    865                                         t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
     865                                        t1, tupleFromTypes( crnt2, end2 ), env, need, have, open,
    866866                                        noWiden(), symtab );
    867867                        } else if ( crnt2 != end2 ) {
    868868                                // try unifying empty tuple with ttype
    869                                 const ast::Type * t2 = (*crnt2)->get_type();
     869                                const ast::Type * t2 = *crnt2;
    870870                                if ( ! Tuples::isTtype( t2 ) ) return false;
    871871                                return unifyExact(
    872                                         tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
     872                                        tupleFromTypes( crnt1, end1 ), t2, env, need, have, open,
    873873                                        noWiden(), symtab );
    874874                        }
     
    877877                }
    878878
    879                 static bool unifyDeclList(
    880                         const std::vector< ast::ptr< ast::DeclWithType > > & list1,
    881                         const std::vector< ast::ptr< ast::DeclWithType > > & list2,
     879                static bool unifyTypeList(
     880                        const std::vector< ast::ptr< ast::Type > > & list1,
     881                        const std::vector< ast::ptr< ast::Type > > & list2,
    882882                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    883883                        const ast::OpenVarSet & open, const ast::SymbolTable & symtab
    884884                ) {
    885                         return unifyDeclList(
     885                        return unifyTypeList(
    886886                                list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open,
    887887                                symtab );
     
    928928                        ) return;
    929929
    930                         if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return;
    931                         if ( ! unifyDeclList(
     930                        if ( ! unifyTypeList( params, params2, tenv, need, have, open, symtab ) ) return;
     931                        if ( ! unifyTypeList(
    932932                                func->returns, func2->returns, tenv, need, have, open, symtab ) ) return;
    933933
     
    12321232        ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func ) {
    12331233                if ( func->returns.empty() ) return new ast::VoidType{};
    1234                 if ( func->returns.size() == 1 ) return func->returns[0]->get_type();
     1234                if ( func->returns.size() == 1 ) return func->returns[0];
    12351235
    12361236                std::vector<ast::ptr<ast::Type>> tys;
    1237                 for ( const ast::DeclWithType * decl : func->returns ) {
    1238                         tys.emplace_back( decl->get_type() );
     1237                for ( const auto & decl : func->returns ) {
     1238                        tys.emplace_back( decl );
    12391239                }
    12401240                return new ast::TupleType{ std::move(tys) };
  • src/SymTab/Autogen.cc

    r33c3ded r223a633  
    339339                } catch ( SemanticErrorException & ) {
    340340                        // okay if decl does not resolve - that means the function should not be generated
    341                         delete dcl;
     341                        // delete dcl;
     342                        delete dcl->statements;
     343                        dcl->statements = nullptr;
     344                        dcl->isDeleted = true;
     345                        definitions.push_back( dcl );
     346                        indexer.addId( dcl );
    342347                }
    343348        }
  • src/SymTab/Mangler.cc

    r33c3ded r223a633  
    551551                        GuardValue( inFunctionType );
    552552                        inFunctionType = true;
    553                         std::vector< ast::ptr< ast::Type > > returnTypes = getTypes( functionType->returns );
    554                         if (returnTypes.empty()) mangleName << Encoding::void_t;
    555                         else accept_each( returnTypes, *visitor );
     553                        if (functionType->returns.empty()) mangleName << Encoding::void_t;
     554                        else accept_each( functionType->returns, *visitor );
    556555                        mangleName << "_";
    557                         std::vector< ast::ptr< ast::Type > > paramTypes = getTypes( functionType->params );
    558                         accept_each( paramTypes, *visitor );
     556                        accept_each( functionType->params, *visitor );
    559557                        mangleName << "_";
    560558                }
  • src/SymTab/Validate.cc

    r33c3ded r223a633  
    13841384        /// Replaces enum types by int, and function/array types in function parameter and return
    13851385        /// lists by appropriate pointers
     1386        /*
    13861387        struct EnumAndPointerDecay_new {
    13871388                const ast::EnumDecl * previsit( const ast::EnumDecl * enumDecl ) {
     
    14341435                }
    14351436        };
     1437        */
    14361438
    14371439        /// expand assertions from a trait instance, performing appropriate type variable substitutions
     
    18371839const ast::Type * validateType(
    18381840                const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) {
    1839         ast::Pass< EnumAndPointerDecay_new > epc;
     1841        // ast::Pass< EnumAndPointerDecay_new > epc;
    18401842        ast::Pass< LinkReferenceToTypes_new > lrt{ loc, symtab };
    18411843        ast::Pass< ForallPointerDecay_new > fpd{ loc };
    18421844
    1843         return type->accept( epc )->accept( lrt )->accept( fpd );
     1845        return type->accept( lrt )->accept( fpd );
    18441846}
    18451847
  • src/SynTree/AggregateDecl.cc

    r33c3ded r223a633  
    2121#include "Common/utility.h"      // for printAll, cloneAll, deleteAll
    2222#include "Declaration.h"         // for AggregateDecl, TypeDecl, Declaration
     23#include "Expression.h"
    2324#include "Initializer.h"
    2425#include "LinkageSpec.h"         // for Spec, linkageName, Cforall
     
    8889const char * StructDecl::typeString() const { return aggrString( kind ); }
    8990
     91StructInstType * StructDecl::makeInst( std::list< Expression * > const & new_parameters ) {
     92        std::list< Expression * > copy_parameters;
     93        cloneAll( new_parameters, copy_parameters );
     94        return makeInst( move( copy( copy_parameters ) ) );
     95}
     96
     97StructInstType * StructDecl::makeInst( std::list< Expression * > && new_parameters ) {
     98        assert( parameters.size() == new_parameters.size() );
     99        StructInstType * type = new StructInstType( noQualifiers, this );
     100        type->parameters = std::move( new_parameters );
     101        return type;
     102}
     103
    90104const char * UnionDecl::typeString() const { return aggrString( Union ); }
    91105
  • src/SynTree/Declaration.h

    r33c3ded r223a633  
    306306        bool is_thread   () { return kind == Thread   ; }
    307307
     308        // Make a type instance of this declaration.
     309        StructInstType * makeInst( std::list< Expression * > const & parameters );
     310        StructInstType * makeInst( std::list< Expression * > && parameters );
     311
    308312        virtual StructDecl * clone() const override { return new StructDecl( *this ); }
    309313        virtual void accept( Visitor & v ) override { v.visit( this ); }
  • src/SynTree/TypeDecl.cc

    r33c3ded r223a633  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Dec 13 15:26:14 2019
    13 // Update Count     : 21
     12// Last Modified On : Thu Oct  8 18:18:55 2020
     13// Update Count     : 22
    1414//
    1515
     
    2121#include "Type.h"            // for Type, Type::StorageClasses
    2222
    23 TypeDecl::TypeDecl( const std::string & name, Type::StorageClasses scs, Type * type, Kind kind, bool sized, Type * init ) : Parent( name, scs, type ), kind( kind ), sized( kind == Ttype || sized ), init( init ) {
     23TypeDecl::TypeDecl( const std::string & name, Type::StorageClasses scs, Type * type, Kind kind, bool sized, Type * init ) :
     24        Parent( name, scs, type ), kind( kind ), sized( kind == Ttype || sized ), init( init ) {
    2425}
    2526
  • src/Virtual/Tables.cc

    r33c3ded r223a633  
    1414//
    1515
     16#include <SynTree/Attribute.h>
    1617#include <SynTree/Declaration.h>
    1718#include <SynTree/Expression.h>
     19#include <SynTree/Statement.h>
    1820#include <SynTree/Type.h>
    1921
     
    3840}
    3941
    40 // Fuse base polymorphic declaration and forall arguments into a new type.
    41 static StructInstType * vtableInstType(
    42                 StructDecl * polyDecl, std::list< Expression * > && parameters ) {
    43         assert( parameters.size() == polyDecl->parameters.size() );
    44         StructInstType * type = new StructInstType(
    45                         Type::Qualifiers( /* Type::Const */ ), polyDecl );
    46         type->parameters = std::move( parameters );
    47         return type;
    48 }
    49 
    5042static ObjectDecl * makeVtableDeclaration(
    5143                StructInstType * type, Initializer * init ) {
     
    6658
    6759ObjectDecl * makeVtableForward( StructInstType * type ) {
     60        assert( type );
    6861        return makeVtableDeclaration( type, nullptr );
    6962}
    7063
    71 ObjectDecl * makeVtableForward(
    72                 StructDecl * polyDecl, std::list< Expression * > && parameters ) {
    73         return makeVtableForward( vtableInstType( polyDecl, std::move( parameters ) ) );
    74 }
    75 
    7664ObjectDecl * makeVtableInstance(
    77                 StructInstType * vtableType, Type * vobject_type, Initializer * init ) {
     65                StructInstType * vtableType, Type * objectType, Initializer * init ) {
     66        assert( vtableType );
     67        assert( objectType );
    7868        StructDecl * vtableStruct = vtableType->baseStruct;
    7969        // Build the initialization
     
    9282                                                new SingleInit( new AddressExpr( new NameExpr( parentInstance ) ) ) );
    9383                        } else if ( std::string( "size" ) == field->name ) {
    94                                 inits.push_back( new SingleInit( new SizeofExpr( vobject_type->clone() ) ) );
     84                                inits.push_back( new SingleInit( new SizeofExpr( objectType->clone() ) ) );
    9585                        } else if ( std::string( "align" ) == field->name ) {
    96                                 inits.push_back( new SingleInit( new AlignofExpr( vobject_type->clone() ) ) );
     86                                inits.push_back( new SingleInit( new AlignofExpr( objectType->clone() ) ) );
    9787                        } else {
    9888                                inits.push_back( new SingleInit( new NameExpr( field->name ) ) );
     
    10898}
    10999
    110 ObjectDecl * makeVtableInstance(
    111                 StructDecl * polyDecl, std::list< Expression * > && parameters,
    112                 Type * vobject, Initializer * init ) {
    113         return makeVtableInstance(
    114                 vtableInstType( polyDecl, std::move( parameters ) ), vobject, init );
     100namespace {
     101        std::string const functionName = "get_exception_vtable";
     102}
     103
     104FunctionDecl * makeGetExceptionForward(
     105                Type * vtableType, Type * exceptType ) {
     106        assert( vtableType );
     107        assert( exceptType );
     108        FunctionType * type = new FunctionType( noQualifiers, false );
     109        vtableType->tq.is_const = true;
     110        type->returnVals.push_back( new ObjectDecl(
     111                "_retvalue",
     112                noStorageClasses,
     113                LinkageSpec::Cforall,
     114                nullptr,
     115                new ReferenceType( noQualifiers, vtableType ),
     116                nullptr,
     117        { new Attribute("unused") }
     118        ) );
     119        type->parameters.push_back( new ObjectDecl(
     120                "__unused",
     121                noStorageClasses,
     122                LinkageSpec::Cforall,
     123                nullptr,
     124                new PointerType( noQualifiers, exceptType ),
     125                nullptr,
     126                { new Attribute("unused") }
     127        ) );
     128        return new FunctionDecl(
     129                functionName,
     130                noStorageClasses,
     131                LinkageSpec::Cforall,
     132                type,
     133                nullptr
     134        );
     135}
     136
     137FunctionDecl * makeGetExceptionFunction(
     138                ObjectDecl * vtableInstance, Type * exceptType ) {
     139        assert( vtableInstance );
     140        assert( exceptType );
     141        FunctionDecl * func = makeGetExceptionForward(
     142                vtableInstance->type->clone(), exceptType );
     143        func->statements = new CompoundStmt( {
     144                new ReturnStmt( new VariableExpr( vtableInstance ) ),
     145        } );
     146        return func;
    115147}
    116148
  • src/Virtual/Tables.h

    r33c3ded r223a633  
    2727bool isVTableInstanceName( std::string const & name );
    2828
    29 /// Converts exceptions into regular structures.
    30 //void ( std::list< Declaration * > & translationUnit );
    31 
    32 ObjectDecl * makeVtableForward( StructInstType * );
    33 ObjectDecl * makeVtableForward( StructDecl *, std::list< Expression * > && );
    34 /* Create a forward definition of a vtable of the given type.
    35  *
    36  * Instead of the virtual table type you may provide the declaration and all
    37  * the forall parameters.
     29ObjectDecl * makeVtableForward( StructInstType * vtableType );
     30/* Create a forward declaration of a vtable of the given type.
     31 * vtableType node is consumed.
    3832 */
    3933
    40 ObjectDecl * makeVtableInstance( StructInstType *, Type *, Initializer * );
    41 ObjectDecl * makeVtableInstance(
    42         StructDecl *, std::list< Expression * > &&, Type *, Initializer * );
     34ObjectDecl * makeVtableInstance( StructInstType * vtableType, Type * objectType,
     35        Initializer * init = nullptr );
    4336/* Create an initialized definition of a vtable.
    44  *
    45  * The parameters are the virtual table type (or the base declaration and the
    46  * forall parameters), the object type and optionally an initializer.
    47  *
    48  * Instead of the virtual table type you may provide the declaration and all
    49  * the forall parameters.
     37 * vtableType and init (if provided) nodes are consumed.
     38 */
     39
     40// Some special code for how exceptions interact with virtual tables.
     41FunctionDecl * makeGetExceptionForward( Type * vtableType, Type * exceptType );
     42/* Create a forward declaration of the exception virtual function
     43 * linking the vtableType to the exceptType. Both nodes are consumed.
     44 */
     45
     46FunctionDecl * makeGetExceptionFunction(
     47        ObjectDecl * vtableInstance, Type * exceptType );
     48/* Create the definition of the exception virtual function.
     49 * exceptType node is consumed.
    5050 */
    5151
  • src/main.cc

    r33c3ded r223a633  
    99// Author           : Peter Buhr and Rob Schluntz
    1010// Created On       : Fri May 15 23:12:02 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Tue May 19 12:03:00 2020
    13 // Update Count     : 634
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Oct  8 18:17:46 2020
     13// Update Count     : 637
    1414//
    1515
     
    451451
    452452
    453 static const char optstring[] = ":c:ghlLmNnpdP:S:twW:D:";
     453static const char optstring[] = ":c:ghlLmNnpdOAP:S:twW:D:";
    454454
    455455enum { PreludeDir = 128 };
     
    478478
    479479static const char * description[] = {
    480         "diagnostic color: never, always, or auto.",          // -c
    481         "wait for gdb to attach",                             // -g
    482         "print help message",                                 // -h
    483         "generate libcfa.c",                                  // -l
    484         "generate line marks",                                // -L
    485         "do not replace main",                                // -m
    486         "do not generate line marks",                         // -N
    487         "do not read prelude",                                // -n
     480        "diagnostic color: never, always, or auto.",            // -c
     481        "wait for gdb to attach",                                                       // -g
     482        "print help message",                                                           // -h
     483        "generate libcfa.c",                                                            // -l
     484        "generate line marks",                                                          // -L
     485        "do not replace main",                                                          // -m
     486        "do not generate line marks",                                           // -N
     487        "do not read prelude",                                                          // -n
    488488        "generate prototypes for prelude functions",            // -p
    489         "don't print output that isn't deterministic",        // -d
    490         "Use the old-ast",                                    // -O
    491         "Use the new-ast",                                    // -A
    492         "print",                                              // -P
     489        "only print deterministic output",                  // -d
     490        "Use the old-ast",                                                                      // -O
     491        "Use the new-ast",                                                                      // -A
     492        "print",                                                                                        // -P
    493493        "<directory> prelude directory for debug/nodebug",      // no flag
    494494        "<option-list> enable profiling information:\n          counters,heap,time,all,none", // -S
    495         "building cfa standard lib",                          // -t
    496         "",                                                   // -w
    497         "",                                                   // -W
    498         "",                                                   // -D
     495        "building cfa standard lib",                                            // -t
     496        "",                                                                                                     // -w
     497        "",                                                                                                     // -W
     498        "",                                                                                                     // -D
    499499}; // description
    500500
Note: See TracChangeset for help on using the changeset viewer.