Changeset 5407cdc for src


Ignore:
Timestamp:
Apr 28, 2021, 4:56:50 PM (4 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:
8d66610
Parents:
feacef9 (diff), b7fd2db6 (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:
35 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    rfeacef9 r5407cdc  
    99// Author           : Thierry Delisle
    1010// Created On       : Thu May 09 15::37::05 2019
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Nov 12 10:07:00 2020
    13 // Update Count     : 34
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Mar 12 18:43:51 2021
     13// Update Count     : 36
    1414//
    1515
     
    327327        const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
    328328                auto decl = new AsmDecl( get<AsmStmt>().accept1( node->stmt ) );
     329                declPostamble( decl, node );
     330                return nullptr;
     331        }
     332
     333        const ast::DirectiveDecl * visit( const ast::DirectiveDecl * node ) override final {
     334                auto decl = new DirectiveDecl( get<DirectiveStmt>().accept1( node->stmt ) );
    329335                declPostamble( decl, node );
    330336                return nullptr;
     
    17691775        }
    17701776
     1777        virtual void visit( const DirectiveDecl * old ) override final {
     1778                auto decl = new ast::DirectiveDecl{
     1779                        old->location,
     1780                        GET_ACCEPT_1(stmt, DirectiveStmt)
     1781                };
     1782                decl->extension  = old->extension;
     1783                decl->uniqueId   = old->uniqueId;
     1784                decl->storage    = { old->storageClasses.val };
     1785
     1786                this->node = decl;
     1787        }
     1788
    17711789        virtual void visit( const StaticAssertDecl * old ) override final {
    17721790                auto decl = new ast::StaticAssertDecl{
  • src/AST/Decl.hpp

    rfeacef9 r5407cdc  
    1010// Created On       : Thu May 9 10:00:00 2019
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jan 11 20:48:38 2021
    13 // Update Count     : 30
     12// Last Modified On : Fri Mar 12 18:25:05 2021
     13// Update Count     : 32
    1414//
    1515
     
    365365};
    366366
     367/// C-preprocessor directive `#...`
     368class DirectiveDecl : public Decl {
     369public:
     370        ptr<DirectiveStmt> stmt;
     371
     372        DirectiveDecl( const CodeLocation & loc, DirectiveStmt * stmt )
     373        : Decl( loc, "", {}, {} ), stmt(stmt) {}
     374
     375        const DirectiveDecl * accept( Visitor & v ) const override { return v.visit( this ); }
     376private:
     377        DirectiveDecl * clone() const override { return new DirectiveDecl( *this ); }
     378        MUTATE_FRIEND
     379};
     380
    367381class StaticAssertDecl : public Decl {
    368382public:
  • src/AST/Expr.cpp

    rfeacef9 r5407cdc  
    260260}
    261261
     262ConstantExpr * ConstantExpr::from_string( const CodeLocation & loc, const std::string & str ) {
     263        const Type * charType = new BasicType( BasicType::Char );
     264        // Adjust the length of the string for the terminator.
     265        const Expr * strSize = from_ulong( loc, str.size() + 1 );
     266        const Type * strType = new ArrayType( charType, strSize, FixedLen, StaticDim );
     267        const std::string strValue = "\"" + str + "\"";
     268        return new ConstantExpr( loc, strType, strValue, std::nullopt );
     269}
     270
    262271ConstantExpr * ConstantExpr::null( const CodeLocation & loc, const Type * ptrType ) {
    263272        return new ConstantExpr{
  • src/AST/Expr.hpp

    rfeacef9 r5407cdc  
    438438        long long int intValue() const;
    439439
    440         /// generates a boolean constant of the given bool
     440        /// Generates a boolean constant of the given bool.
    441441        static ConstantExpr * from_bool( const CodeLocation & loc, bool b );
    442         /// generates an integer constant of the given int
     442        /// Generates an integer constant of the given int.
    443443        static ConstantExpr * from_int( const CodeLocation & loc, int i );
    444         /// generates an integer constant of the given unsigned long int
     444        /// Generates an integer constant of the given unsigned long int.
    445445        static ConstantExpr * from_ulong( const CodeLocation & loc, unsigned long i );
    446         /// generates a null pointer value for the given type. void * if omitted.
     446        /// Generates a string constant from the given string (char type, unquoted string).
     447        static ConstantExpr * from_string( const CodeLocation & loc, const std::string & string );
     448        /// Generates a null pointer value for the given type. void * if omitted.
    447449        static ConstantExpr * null( const CodeLocation & loc, const Type * ptrType = nullptr );
    448450
  • src/AST/Fwd.hpp

    rfeacef9 r5407cdc  
    99// Author           : Andrew Beach
    1010// Created On       : Wed May  8 16:05:00 2019
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Jul 23 14:15:00 2020
    13 // Update Count     : 2
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Mar 12 18:37:39 2021
     13// Update Count     : 4
    1414//
    1515
     
    3535class TypedefDecl;
    3636class AsmDecl;
     37class DirectiveDecl;
    3738class StaticAssertDecl;
    3839
  • src/AST/Node.cpp

    rfeacef9 r5407cdc  
    99// Author           : Thierry Delisle
    1010// Created On       : Thu May 16 14:16:00 2019
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jun  5 10:21:00 2020
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Mar 12 18:25:06 2021
     13// Update Count     : 2
    1414//
    1515
     
    130130template class ast::ptr_base< ast::AsmDecl, ast::Node::ref_type::weak >;
    131131template class ast::ptr_base< ast::AsmDecl, ast::Node::ref_type::strong >;
     132template class ast::ptr_base< ast::DirectiveDecl, ast::Node::ref_type::weak >;
     133template class ast::ptr_base< ast::DirectiveDecl, ast::Node::ref_type::strong >;
    132134template class ast::ptr_base< ast::StaticAssertDecl, ast::Node::ref_type::weak >;
    133135template class ast::ptr_base< ast::StaticAssertDecl, ast::Node::ref_type::strong >;
  • src/AST/Pass.hpp

    rfeacef9 r5407cdc  
    139139        const ast::Decl *             visit( const ast::TypedefDecl          * ) override final;
    140140        const ast::AsmDecl *          visit( const ast::AsmDecl              * ) override final;
     141        const ast::DirectiveDecl *    visit( const ast::DirectiveDecl        * ) override final;
    141142        const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl     * ) override final;
    142143        const ast::CompoundStmt *     visit( const ast::CompoundStmt         * ) override final;
  • src/AST/Pass.impl.hpp

    rfeacef9 r5407cdc  
    646646
    647647//--------------------------------------------------------------------------
     648// DirectiveDecl
     649template< typename core_t >
     650const ast::DirectiveDecl * ast::Pass< core_t >::visit( const ast::DirectiveDecl * node ) {
     651        VISIT_START( node );
     652
     653        VISIT(
     654                maybe_accept( node, &DirectiveDecl::stmt );
     655        )
     656
     657        VISIT_END( DirectiveDecl, node );
     658}
     659
     660//--------------------------------------------------------------------------
    648661// StaticAssertDecl
    649662template< typename core_t >
  • src/AST/Print.cpp

    rfeacef9 r5407cdc  
    387387
    388388        virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
     389                safe_print( node->stmt );
     390                return node;
     391        }
     392
     393        virtual const ast::DirectiveDecl * visit( const ast::DirectiveDecl * node ) override final {
    389394                safe_print( node->stmt );
    390395                return node;
  • src/AST/Type.cpp

    rfeacef9 r5407cdc  
    105105}
    106106
     107// --- BaseInstType
     108
    107109std::vector<readonly<Decl>> BaseInstType::lookup( const std::string& name ) const {
    108110        assertf( aggr(), "Must have aggregate to perform lookup" );
     
    119121template<typename decl_t>
    120122SueInstType<decl_t>::SueInstType(
    121         const decl_t * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
    122 : BaseInstType( b->name, q, move(as) ), base( b ) {}
     123        const base_type * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
     124: BaseInstType( b->name, q, std::move(as) ), base( b ) {}
    123125
    124126template<typename decl_t>
     
    142144        const TraitDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
    143145: BaseInstType( b->name, q, move(as) ), base( b ) {}
     146
     147// --- TypeInstType
    144148
    145149void TypeInstType::set_base( const TypeDecl * b ) {
  • src/AST/Visitor.hpp

    rfeacef9 r5407cdc  
    99// Author           : Andrew Beach
    1010// Created On       : Thr May 9 15:28:00 2019
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr May 9 15:33:00 2019
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Mar 12 18:25:07 2021
     13// Update Count     : 1
    1414//
    1515
     
    3131    virtual const ast::Decl *             visit( const ast::TypedefDecl          * ) = 0;
    3232    virtual const ast::AsmDecl *          visit( const ast::AsmDecl              * ) = 0;
     33    virtual const ast::DirectiveDecl *    visit( const ast::DirectiveDecl        * ) = 0;
    3334    virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl     * ) = 0;
    3435    virtual const ast::CompoundStmt *     visit( const ast::CompoundStmt         * ) = 0;
  • src/CodeGen/CodeGenerator.cc

    rfeacef9 r5407cdc  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 16 08:32:48 2020
    13 // Update Count     : 532
     12// Last Modified On : Fri Mar 12 19:00:42 2021
     13// Update Count     : 536
    1414//
    1515#include "CodeGenerator.h"
     
    935935                if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *visitor );
    936936                output << " )";
     937        }
     938
     939        void CodeGenerator::postvisit( DirectiveDecl * directiveDecl ) {
     940                output << endl << directiveDecl->get_stmt()->directive; // endl prevents spaces before directive
    937941        }
    938942
  • src/CodeGen/CodeGenerator.h

    rfeacef9 r5407cdc  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 16 03:58:31 2020
    13 // Update Count     : 62
     12// Last Modified On : Fri Mar 12 18:35:38 2021
     13// Update Count     : 63
    1414//
    1515
     
    105105                void postvisit( DirectiveStmt * );
    106106                void postvisit( AsmDecl * );                                    // special: statement in declaration context
     107                void postvisit( DirectiveDecl * );                              // special: statement in declaration context
    107108                void postvisit( IfStmt * );
    108109                void postvisit( SwitchStmt * );
  • src/Common/CodeLocationTools.cpp

    rfeacef9 r5407cdc  
    99// Author           : Andrew Beach
    1010// Created On       : Fri Dec  4 15:42:00 2020
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Dec  9  9:42:00 2020
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Mar 12 18:35:37 2021
     13// Update Count     : 2
    1414//
    1515
     
    102102    macro(TypedefDecl, Decl) \
    103103    macro(AsmDecl, AsmDecl) \
     104    macro(DirectiveDecl, DirectiveDecl) \
    104105    macro(StaticAssertDecl, StaticAssertDecl) \
    105106    macro(CompoundStmt, CompoundStmt) \
  • src/Common/PassVisitor.h

    rfeacef9 r5407cdc  
    7777        virtual void visit( AsmDecl * asmDecl ) override final;
    7878        virtual void visit( const AsmDecl * asmDecl ) override final;
     79        virtual void visit( DirectiveDecl * directiveDecl ) override final;
     80        virtual void visit( const DirectiveDecl * directiveDecl ) override final;
    7981        virtual void visit( StaticAssertDecl * assertDecl ) override final;
    8082        virtual void visit( const StaticAssertDecl * assertDecl ) override final;
     
    261263        virtual Declaration * mutate( TypedefDecl * typeDecl ) override final;
    262264        virtual AsmDecl * mutate( AsmDecl * asmDecl ) override final;
     265        virtual DirectiveDecl * mutate( DirectiveDecl * directiveDecl ) override final;
    263266        virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) override final;
    264267
  • src/Common/PassVisitor.impl.h

    rfeacef9 r5407cdc  
    973973
    974974//--------------------------------------------------------------------------
     975// DirectiveDecl
     976template< typename pass_type >
     977void PassVisitor< pass_type >::visit( DirectiveDecl * node ) {
     978        VISIT_START( node );
     979
     980        maybeAccept_impl( node->stmt, *this );
     981
     982        VISIT_END( node );
     983}
     984
     985template< typename pass_type >
     986void PassVisitor< pass_type >::visit( const DirectiveDecl * node ) {
     987        VISIT_START( node );
     988
     989        maybeAccept_impl( node->stmt, *this );
     990
     991        VISIT_END( node );
     992}
     993
     994template< typename pass_type >
     995DirectiveDecl * PassVisitor< pass_type >::mutate( DirectiveDecl * node ) {
     996        MUTATE_START( node );
     997
     998        maybeMutate_impl( node->stmt, *this );
     999
     1000        MUTATE_END( DirectiveDecl, node );
     1001}
     1002
     1003//--------------------------------------------------------------------------
    9751004// StaticAssertDecl
    9761005template< typename pass_type >
  • src/Concurrency/Keywords.cc

    rfeacef9 r5407cdc  
    4242
    4343namespace Concurrency {
     44        inline static std::string getTypeIdName( std::string const & exception_name ) {
     45                return exception_name.empty() ? std::string() : Virtual::typeIdType( exception_name );
     46        }
    4447        inline static std::string getVTableName( std::string const & exception_name ) {
    45                 return exception_name.empty() ? std::string() : Virtual::vtableTypeName(exception_name);
     48                return exception_name.empty() ? std::string() : Virtual::vtableTypeName( exception_name );
    4649        }
    4750
     
    7578                  type_name( type_name ), field_name( field_name ), getter_name( getter_name ),
    7679                  context_error( context_error ), exception_name( exception_name ),
     80                  typeid_name( getTypeIdName( exception_name ) ),
    7781                  vtable_name( getVTableName( exception_name ) ),
    7882                  needs_main( needs_main ), cast_target( cast_target ) {}
     
    8488
    8589                void handle( StructDecl * );
     90                void addTypeId( StructDecl * );
    8691                void addVtableForward( StructDecl * );
    8792                FunctionDecl * forwardDeclare( StructDecl * );
     
    99104                const std::string context_error;
    100105                const std::string exception_name;
     106                const std::string typeid_name;
    101107                const std::string vtable_name;
    102108                bool needs_main;
     
    106112                FunctionDecl * dtor_decl = nullptr;
    107113                StructDecl * except_decl = nullptr;
     114                StructDecl * typeid_decl = nullptr;
    108115                StructDecl * vtable_decl = nullptr;
    109116        };
     
    393400                        except_decl = decl;
    394401                }
     402                else if ( !typeid_decl && typeid_name == decl->name && decl->body ) {
     403                        typeid_decl = decl;
     404                }
    395405                else if ( !vtable_decl && vtable_name == decl->name && decl->body ) {
    396406                        vtable_decl = decl;
     
    404414                if ( type_decl && isDestructorFor( decl, type_decl ) )
    405415                        dtor_decl = decl;
    406                 else if ( vtable_name.empty() )
    407                         ;
    408                 else if( !decl->has_body() )
     416                else if ( vtable_name.empty() || !decl->has_body() )
    409417                        ;
    410418                else if ( auto param = isMainFor( decl, cast_target ) ) {
     
    418426                        std::list< Expression * > poly_args = { new TypeExpr( struct_type->clone() ) };
    419427                        ObjectDecl * vtable_object = Virtual::makeVtableInstance(
     428                                "_default_vtable_object_declaration",
    420429                                vtable_decl->makeInst( poly_args ), struct_type, nullptr );
    421430                        declsToAddAfter.push_back( vtable_object );
     431                        declsToAddAfter.push_back(
     432                                new ObjectDecl(
     433                                        Virtual::concurrentDefaultVTableName(),
     434                                        Type::Const,
     435                                        LinkageSpec::Cforall,
     436                                        /* bitfieldWidth */ nullptr,
     437                                        new ReferenceType( Type::Const, vtable_object->type->clone() ),
     438                                        new SingleInit( new VariableExpr( vtable_object ) )
     439                                )
     440                        );
    422441                        declsToAddAfter.push_back( Virtual::makeGetExceptionFunction(
    423442                                vtable_object, except_decl->makeInst( std::move( poly_args ) )
     
    448467                if( !dtor_decl ) SemanticError( decl, context_error );
    449468
    450                 addVtableForward( decl );
     469                if ( !exception_name.empty() ) {
     470                        if( !typeid_decl ) SemanticError( decl, context_error );
     471                        if( !vtable_decl ) SemanticError( decl, context_error );
     472
     473                        addTypeId( decl );
     474                        addVtableForward( decl );
     475                }
    451476                FunctionDecl * func = forwardDeclare( decl );
    452477                ObjectDecl * field = addField( decl );
     
    454479        }
    455480
     481        void ConcurrentSueKeyword::addTypeId( StructDecl * decl ) {
     482                assert( typeid_decl );
     483                StructInstType typeid_type( Type::Const, typeid_decl );
     484                typeid_type.parameters.push_back( new TypeExpr(
     485                        new StructInstType( noQualifiers, decl )
     486                        ) );
     487                declsToAddBefore.push_back( Virtual::makeTypeIdInstance( &typeid_type ) );
     488        }
     489
    456490        void ConcurrentSueKeyword::addVtableForward( StructDecl * decl ) {
    457                 if ( vtable_decl ) {
    458                         std::list< Expression * > poly_args = {
    459                                 new TypeExpr( new StructInstType( noQualifiers, decl ) ),
    460                         };
    461                         declsToAddBefore.push_back( Virtual::makeGetExceptionForward(
    462                                 vtable_decl->makeInst( poly_args ),
    463                                 except_decl->makeInst( poly_args )
    464                         ) );
    465                         declsToAddBefore.push_back( Virtual::makeVtableForward(
    466                                 vtable_decl->makeInst( move( poly_args ) ) ) );
    467                 // Its only an error if we want a vtable and don't have one.
    468                 } else if ( ! vtable_name.empty() ) {
    469                         SemanticError( decl, context_error );
    470                 }
     491                assert( vtable_decl );
     492                std::list< Expression * > poly_args = {
     493                        new TypeExpr( new StructInstType( noQualifiers, decl ) ),
     494                };
     495                declsToAddBefore.push_back( Virtual::makeGetExceptionForward(
     496                        vtable_decl->makeInst( poly_args ),
     497                        except_decl->makeInst( poly_args )
     498                ) );
     499                ObjectDecl * vtable_object = Virtual::makeVtableForward(
     500                        "_default_vtable_object_declaration",
     501                        vtable_decl->makeInst( move( poly_args ) ) );
     502                declsToAddBefore.push_back( vtable_object );
     503                declsToAddBefore.push_back(
     504                        new ObjectDecl(
     505                                Virtual::concurrentDefaultVTableName(),
     506                                Type::Const,
     507                                LinkageSpec::Cforall,
     508                                /* bitfieldWidth */ nullptr,
     509                                new ReferenceType( Type::Const, vtable_object->type->clone() ),
     510                                /* init */ nullptr
     511                        )
     512                );
    471513        }
    472514
  • src/Parser/DeclarationNode.cc

    rfeacef9 r5407cdc  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jan 11 20:58:07 2021
    13 // Update Count     : 1137
     12// Last Modified On : Tue Mar 23 08:44:08 2021
     13// Update Count     : 1149
    1414//
    1515
     
    167167}
    168168
    169 DeclarationNode * DeclarationNode::newFunction( const string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ) {
    170         DeclarationNode * newnode = new DeclarationNode;
    171         newnode->name = name;
    172         newnode->type = new TypeData( TypeData::Function );
    173         newnode->type->function.params = param;
    174         newnode->type->function.body = body;
    175 
    176         if ( ret ) {
    177                 newnode->type->base = ret->type;
    178                 ret->type = nullptr;
    179                 delete ret;
    180         } // if
    181 
    182         return newnode;
    183 } // DeclarationNode::newFunction
    184 
    185 
    186169DeclarationNode * DeclarationNode::newStorageClass( Type::StorageClasses sc ) {
    187170        DeclarationNode * newnode = new DeclarationNode;
     
    237220        return newnode;
    238221} // DeclarationNode::newForall
    239 
    240 DeclarationNode * DeclarationNode::newFromTypedef( const string * name ) {
    241         DeclarationNode * newnode = new DeclarationNode;
    242         newnode->type = new TypeData( TypeData::SymbolicInst );
    243         newnode->type->symbolic.name = name;
    244         newnode->type->symbolic.isTypedef = true;
    245         newnode->type->symbolic.params = nullptr;
    246         return newnode;
    247 } // DeclarationNode::newFromTypedef
    248222
    249223DeclarationNode * DeclarationNode::newFromGlobalScope() {
     
    289263} // DeclarationNode::newEnum
    290264
     265DeclarationNode * DeclarationNode::newName( const string * name ) {
     266        DeclarationNode * newnode = new DeclarationNode;
     267        assert( ! newnode->name );
     268        newnode->name = name;
     269        return newnode;
     270} // DeclarationNode::newName
     271
    291272DeclarationNode * DeclarationNode::newEnumConstant( const string * name, ExpressionNode * constant ) {
    292         DeclarationNode * newnode = new DeclarationNode;
    293         newnode->name = name;
     273        DeclarationNode * newnode = newName( name );
    294274        newnode->enumeratorValue.reset( constant );
    295275        return newnode;
    296276} // DeclarationNode::newEnumConstant
    297277
    298 DeclarationNode * DeclarationNode::newName( const string * name ) {
    299         DeclarationNode * newnode = new DeclarationNode;
    300         newnode->name = name;
    301         return newnode;
    302 } // DeclarationNode::newName
     278DeclarationNode * DeclarationNode::newFromTypedef( const string * name ) {
     279        DeclarationNode * newnode = new DeclarationNode;
     280        newnode->type = new TypeData( TypeData::SymbolicInst );
     281        newnode->type->symbolic.name = name;
     282        newnode->type->symbolic.isTypedef = true;
     283        newnode->type->symbolic.params = nullptr;
     284        return newnode;
     285} // DeclarationNode::newFromTypedef
    303286
    304287DeclarationNode * DeclarationNode::newFromTypeGen( const string * name, ExpressionNode * params ) {
     
    312295
    313296DeclarationNode * DeclarationNode::newTypeParam( TypeDecl::Kind tc, const string * name ) {
    314         DeclarationNode * newnode = new DeclarationNode;
     297        DeclarationNode * newnode = newName( name );
    315298        newnode->type = nullptr;
    316         assert( ! newnode->name );
    317 //      newnode->variable.name = name;
    318         newnode->name = name;
    319299        newnode->variable.tyClass = tc;
    320300        newnode->variable.assertions = nullptr;
     
    343323
    344324DeclarationNode * DeclarationNode::newTypeDecl( const string * name, DeclarationNode * typeParams ) {
    345         DeclarationNode * newnode = new DeclarationNode;
    346         newnode->name = name;
     325        DeclarationNode * newnode = newName( name );
    347326        newnode->type = new TypeData( TypeData::Symbolic );
    348327        newnode->type->symbolic.isTypedef = false;
     
    417396} // DeclarationNode::newBuiltinType
    418397
     398DeclarationNode * DeclarationNode::newFunction( const string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ) {
     399        DeclarationNode * newnode = newName( name );
     400        newnode->type = new TypeData( TypeData::Function );
     401        newnode->type->function.params = param;
     402        newnode->type->function.body = body;
     403
     404        if ( ret ) {
     405                newnode->type->base = ret->type;
     406                ret->type = nullptr;
     407                delete ret;
     408        } // if
     409
     410        return newnode;
     411} // DeclarationNode::newFunction
     412
    419413DeclarationNode * DeclarationNode::newAttribute( const string * name, ExpressionNode * expr ) {
    420414        DeclarationNode * newnode = new DeclarationNode;
     
    424418        newnode->attributes.push_back( new Attribute( *name, exprs ) );
    425419        delete name;
     420        return newnode;
     421}
     422
     423DeclarationNode * DeclarationNode::newDirectiveStmt( StatementNode * stmt ) {
     424        DeclarationNode * newnode = new DeclarationNode;
     425        newnode->directiveStmt = stmt;
    426426        return newnode;
    427427}
     
    879879}
    880880
    881 DeclarationNode * DeclarationNode::cloneType( string * newName ) {
    882         DeclarationNode * newnode = new DeclarationNode;
     881DeclarationNode * DeclarationNode::cloneType( string * name ) {
     882        DeclarationNode * newnode = newName( name );
    883883        newnode->type = maybeClone( type );
    884884        newnode->copySpecifiers( this );
    885         assert( newName );
    886         newnode->name = newName;
    887885        return newnode;
    888886}
     
    10721070                return new AsmDecl( strict_dynamic_cast<AsmStmt *>( asmStmt->build() ) );
    10731071        } // if
     1072        if ( directiveStmt ) {
     1073                return new DirectiveDecl( strict_dynamic_cast<DirectiveStmt *>( directiveStmt->build() ) );
     1074        } // if
    10741075
    10751076        if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
  • src/Parser/ParseNode.h

    rfeacef9 r5407cdc  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jan  3 18:23:01 2021
    13 // Update Count     : 896
     12// Last Modified On : Fri Mar 12 15:19:04 2021
     13// Update Count     : 897
    1414//
    1515
     
    249249        static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
    250250        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
     251        static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
    251252        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
    252253        static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
     
    345346        std::string error;
    346347        StatementNode * asmStmt = nullptr;
     348        StatementNode * directiveStmt = nullptr;
    347349
    348350        static UniqueName anonymous;
  • src/Parser/TypeData.h

    rfeacef9 r5407cdc  
    77// TypeData.h --
    88//
    9 // Author           : Rodolfo G. Esteves
     9// Author           : Peter A. Buhr
    1010// Created On       : Sat May 16 15:18:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Dec 13 23:42:35 2019
    13 // Update Count     : 199
     12// Last Modified On : Sat Mar 27 09:05:35 2021
     13// Update Count     : 200
    1414//
    1515
    1616#pragma once
    1717
    18 #include <iosfwd>                // for ostream
    19 #include <list>                  // for list
    20 #include <string>                // for string
     18#include <iosfwd>                                                                               // for ostream
     19#include <list>                                                                                 // for list
     20#include <string>                                                                               // for string
    2121
    22 #include "ParseNode.h"           // for DeclarationNode, DeclarationNode::Ag...
    23 #include "SynTree/LinkageSpec.h" // for Spec
    24 #include "SynTree/Type.h"        // for Type, ReferenceToType (ptr only)
    25 #include "SynTree/SynTree.h"     // for Visitor Nodes
     22#include "ParseNode.h"                                                                  // for DeclarationNode, DeclarationNode::Ag...
     23#include "SynTree/LinkageSpec.h"                                                // for Spec
     24#include "SynTree/Type.h"                                                               // for Type, ReferenceToType (ptr only)
     25#include "SynTree/SynTree.h"                                                    // for Visitor Nodes
    2626
    2727struct TypeData {
     
    3333                const std::string * name = nullptr;
    3434                DeclarationNode * params = nullptr;
    35                 ExpressionNode * actuals = nullptr;                                             // holds actual parameters later applied to AggInst
     35                ExpressionNode * actuals = nullptr;                             // holds actual parameters later applied to AggInst
    3636                DeclarationNode * fields = nullptr;
    3737                bool body;
     
    6262
    6363        struct Function_t {
    64                 mutable DeclarationNode * params = nullptr;                             // mutables modified in buildKRFunction
    65                 mutable DeclarationNode * idList = nullptr;                             // old-style
     64                mutable DeclarationNode * params = nullptr;             // mutables modified in buildKRFunction
     65                mutable DeclarationNode * idList = nullptr;             // old-style
    6666                mutable DeclarationNode * oldDeclList = nullptr;
    6767                StatementNode * body = nullptr;
    68                 ExpressionNode * withExprs = nullptr;                                           // expressions from function's with_clause
     68                ExpressionNode * withExprs = nullptr;                   // expressions from function's with_clause
    6969        };
    7070
  • src/Parser/TypedefTable.cc

    rfeacef9 r5407cdc  
    1010// Created On       : Sat May 16 15:20:13 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 15 08:06:36 2020
    13 // Update Count     : 259
     12// Last Modified On : Mon Mar 15 20:56:47 2021
     13// Update Count     : 260
    1414//
    1515
     
    8989        debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << " level " << level << " note " << kindTable.getNote( kindTable.currentScope() - 1 ).level << endl );
    9090        auto ret = kindTable.insertAt( scope, identifier, kind );
    91         if ( ! ret.second ) ret.first->second = kind;   // exists => update
     91        if ( ! ret.second ) ret.first->second = kind;           // exists => update
    9292} // TypedefTable::addToEnclosingScope
    9393
  • src/Parser/lex.ll

    rfeacef9 r5407cdc  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Tue Oct  6 18:15:41 2020
    13  * Update Count     : 743
     12 * Last Modified On : Thu Apr  1 13:22:31 2021
     13 * Update Count     : 754
    1414 */
    1515
     
    221221break                   { KEYWORD_RETURN(BREAK); }
    222222case                    { KEYWORD_RETURN(CASE); }
    223 catch                   { KEYWORD_RETURN(CATCH); }                              // CFA
    224 catchResume             { KEYWORD_RETURN(CATCHRESUME); }                // CFA
     223catch                   { QKEYWORD_RETURN(CATCH); }                             // CFA
     224catchResume             { QKEYWORD_RETURN(CATCHRESUME); }               // CFA
    225225char                    { KEYWORD_RETURN(CHAR); }
    226226choose                  { KEYWORD_RETURN(CHOOSE); }                             // CFA
     
    247247fallthrough             { KEYWORD_RETURN(FALLTHROUGH); }                // CFA
    248248fallthru                { KEYWORD_RETURN(FALLTHRU); }                   // CFA
    249 finally                 { KEYWORD_RETURN(FINALLY); }                    // CFA
     249finally                 { QKEYWORD_RETURN(FINALLY); }                   // CFA
     250fixup                   { QKEYWORD_RETURN(FIXUP); }                             // CFA
    250251float                   { KEYWORD_RETURN(FLOAT); }
    251252__float80               { KEYWORD_RETURN(uuFLOAT80); }                  // GCC
     
    287288or                              { QKEYWORD_RETURN(WOR); }                               // CFA
    288289otype                   { KEYWORD_RETURN(OTYPE); }                              // CFA
     290recover                 { QKEYWORD_RETURN(RECOVER); }                   // CFA
    289291register                { KEYWORD_RETURN(REGISTER); }
     292report                  { KEYWORD_RETURN(THROWRESUME); }                // CFA
    290293restrict                { KEYWORD_RETURN(RESTRICT); }                   // C99
    291294__restrict              { KEYWORD_RETURN(RESTRICT); }                   // GCC
     
    315318__typeof                { KEYWORD_RETURN(TYPEOF); }                             // GCC
    316319__typeof__              { KEYWORD_RETURN(TYPEOF); }                             // GCC
     320typeid                  { KEYWORD_RETURN(TYPEID); }                             // GCC
    317321union                   { KEYWORD_RETURN(UNION); }
    318322__uint128_t             { KEYWORD_RETURN(UINT128); }                    // GCC
     
    324328__volatile              { KEYWORD_RETURN(VOLATILE); }                   // GCC
    325329__volatile__    { KEYWORD_RETURN(VOLATILE); }                   // GCC
    326 waitfor                 { KEYWORD_RETURN(WAITFOR); }
    327 when                    { KEYWORD_RETURN(WHEN); }
     330vtable                  { KEYWORD_RETURN(VTABLE); }                             // CFA
     331waitfor                 { KEYWORD_RETURN(WAITFOR); }                    // CFA
     332when                    { KEYWORD_RETURN(WHEN); }                               // CFA
    328333while                   { KEYWORD_RETURN(WHILE); }
    329334with                    { KEYWORD_RETURN(WITH); }                               // CFA
  • src/Parser/parser.yy

    rfeacef9 r5407cdc  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb  3 18:30:12 2021
    13 // Update Count     : 4700
     12// Last Modified On : Mon Apr 26 18:41:54 2021
     13// Update Count     : 4990
    1414//
    1515
     
    3232//
    3333// 1. designation with and without '=' (use ':' instead)
    34 // 2. attributes not allowed in parenthesis of declarator
     34
    3535//
    3636// All of the syntactic extensions for GCC C are marked with the comment "GCC". The second extensions are for Cforall
     
    211211} // forCtrl
    212212
    213 bool forall = false, yyy = false;                                               // aggregate have one or more forall qualifiers ?
     213bool forall = false;                                                                    // aggregate have one or more forall qualifiers ?
    214214
    215215// https://www.gnu.org/software/bison/manual/bison.html#Location-Type
     
    264264%token RESTRICT                                                                                 // C99
    265265%token ATOMIC                                                                                   // C11
    266 %token FORALL MUTEX VIRTUAL COERCE                                              // CFA
     266%token FORALL MUTEX VIRTUAL VTABLE COERCE                               // CFA
    267267%token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED
    268268%token BOOL COMPLEX IMAGINARY                                                   // C99
     
    270270%token uFLOAT16 uFLOAT32 uFLOAT32X uFLOAT64 uFLOAT64X uFLOAT128 // GCC
    271271%token ZERO_T ONE_T                                                                             // CFA
    272 %token VALIST                                                                                   // GCC
    273 %token AUTO_TYPE                                                                                // GCC
    274 %token TYPEOF BASETYPEOF LABEL                                                  // GCC
     272%token SIZEOF TYPEOF VALIST AUTO_TYPE                                   // GCC
     273%token OFFSETOF BASETYPEOF TYPEID                                               // CFA
    275274%token ENUM STRUCT UNION
    276275%token EXCEPTION                                                                                // CFA
    277276%token GENERATOR COROUTINE MONITOR THREAD                               // CFA
    278277%token OTYPE FTYPE DTYPE TTYPE TRAIT                                    // CFA
    279 %token SIZEOF OFFSETOF
    280278// %token RESUME                                                                                        // CFA
     279%token LABEL                                                                                    // GCC
    281280%token SUSPEND                                                                                  // CFA
    282281%token ATTRIBUTE EXTENSION                                                              // GCC
    283282%token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN
    284 %token CHOOSE DISABLE ENABLE FALLTHRU FALLTHROUGH TRY CATCH CATCHRESUME FINALLY THROW THROWRESUME AT WITH WHEN WAITFOR // CFA
     283%token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR    // CFA
     284%token DISABLE ENABLE TRY THROW THROWRESUME AT                  // CFA
    285285%token ASM                                                                                              // C99, extension ISO/IEC 9899:1999 Section J.5.10(1)
    286286%token ALIGNAS ALIGNOF GENERIC STATICASSERT                             // C11
    287287
    288288// names and constants: lexer differentiates between identifier and typedef names
    289 %token<tok> IDENTIFIER                  QUOTED_IDENTIFIER               TYPEDEFname                             TYPEGENname
    290 %token<tok> TIMEOUT                             WOR
    291 %token<tok> INTEGERconstant             CHARACTERconstant               STRINGliteral
     289%token<tok> IDENTIFIER          QUOTED_IDENTIFIER       TYPEDEFname             TYPEGENname
     290%token<tok> TIMEOUT                     WOR                                     CATCH                   RECOVER                 CATCHRESUME             FIXUP           FINALLY         // CFA
     291%token<tok> INTEGERconstant     CHARACTERconstant       STRINGliteral
    292292%token<tok> DIRECTIVE
    293293// Floating point constant is broken into three kinds of tokens because of the ambiguity with tuple indexing and
     
    321321%type<en> constant
    322322%type<en> tuple                                                 tuple_expression_list
    323 %type<op> ptrref_operator                               unary_operator                          assignment_operator
     323%type<op> ptrref_operator                               unary_operator                          assignment_operator                     simple_assignment_operator      compound_assignment_operator
    324324%type<en> primary_expression                    postfix_expression                      unary_expression
    325325%type<en> cast_expression_list                  cast_expression                         exponential_expression          multiplicative_expression       additive_expression
     
    373373
    374374%type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type
     375%type<decl> vtable vtable_opt default_opt
    375376
    376377%type<decl> trait_declaration trait_declaration_list trait_declaring_list trait_specifier
     
    428429
    429430%type<decl> type_declaration_specifier type_type_specifier type_name typegen_name
    430 %type<decl> typedef typedef_declaration typedef_expression
     431%type<decl> typedef_name typedef_declaration typedef_expression
    431432
    432433%type<decl> variable_type_redeclarator type_ptr type_array type_function
     
    440441
    441442%type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list
    442 %type<decl> type_specifier type_specifier_nobody enum_specifier_nobody
     443%type<decl> type_specifier type_specifier_nobody
    443444
    444445%type<decl> variable_declarator variable_ptr variable_array variable_function
    445446%type<decl> variable_abstract_declarator variable_abstract_ptr variable_abstract_array variable_abstract_function
    446447
    447 %type<decl> attribute_list_opt attribute_list attribute_opt attribute attribute_name_list attribute_name
     448%type<decl> attribute_list_opt attribute_list attribute attribute_name_list attribute_name
    448449
    449450// initializers
     
    462463// Order of these lines matters (low-to-high precedence). THEN is left associative over WOR/TIMEOUT/ELSE, WOR is left
    463464// associative over TIMEOUT/ELSE, and TIMEOUT is left associative over ELSE.
    464 %precedence THEN        // rule precedence for IF/WAITFOR statement
    465 %precedence WOR         // token precedence for start of WOR in WAITFOR statement
    466 %precedence TIMEOUT     // token precedence for start of TIMEOUT in WAITFOR statement
    467 %precedence ELSE        // token precedence for start of else clause in IF/WAITFOR statement
     465%precedence THEN                // rule precedence for IF/WAITFOR statement
     466%precedence WOR                 // token precedence for start of WOR in WAITFOR statement
     467%precedence TIMEOUT             // token precedence for start of TIMEOUT in WAITFOR statement
     468%precedence CATCH               // token precedence for start of TIMEOUT in WAITFOR statement
     469%precedence RECOVER             // token precedence for start of TIMEOUT in WAITFOR statement
     470%precedence CATCHRESUME // token precedence for start of TIMEOUT in WAITFOR statement
     471%precedence FIXUP               // token precedence for start of TIMEOUT in WAITFOR statement
     472%precedence FINALLY             // token precedence for start of TIMEOUT in WAITFOR statement
     473%precedence ELSE                // token precedence for start of else clause in IF/WAITFOR statement
     474
    468475
    469476// Handle shift/reduce conflict for generic type by shifting the '(' token. For example, this string is ambiguous:
     
    544551        TIMEOUT
    545552        | WOR
     553        | CATCH
     554        | RECOVER
     555        | CATCHRESUME
     556        | FIXUP
     557        | FINALLY
    546558        ;
    547559
     
    774786        | OFFSETOF '(' type_no_function ',' identifier ')'
    775787                { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); }
     788        | TYPEID '(' type_no_function ')'
     789                {
     790                        SemanticError( yylloc, "typeid name is currently unimplemented." ); $$ = nullptr;
     791                        // $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) );
     792                }
    776793        ;
    777794
     
    795812                { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
    796813        | '(' aggregate_control '&' ')' cast_expression         // CFA
     814                { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
     815        | '(' aggregate_control '*' ')' cast_expression         // CFA
    797816                { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
    798817        | '(' VIRTUAL ')' cast_expression                                       // CFA
     
    939958
    940959assignment_operator:
     960        simple_assignment_operator
     961        | compound_assignment_operator
     962        ;
     963
     964simple_assignment_operator:
    941965        '='                                                                                     { $$ = OperKinds::Assign; }
    942         | ATassign                                                                      { $$ = OperKinds::AtAssn; }
    943         | EXPassign                                                                     { $$ = OperKinds::ExpAssn; }
     966        | ATassign                                                                      { $$ = OperKinds::AtAssn; } // CFA
     967        ;
     968
     969compound_assignment_operator:
     970        EXPassign                                                                       { $$ = OperKinds::ExpAssn; }
    944971        | MULTassign                                                            { $$ = OperKinds::MulAssn; }
    945972        | DIVassign                                                                     { $$ = OperKinds::DivAssn; }
     
    10191046                { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }
    10201047        | '{' push
    1021           local_label_declaration_opt                                           // GCC, local labels
     1048          local_label_declaration_opt                                           // GCC, local labels appear at start of block
    10221049          statement_decl_list                                                           // C99, intermix declarations and statements
    10231050          pop '}'
     
    12171244        | comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA
    12181245                { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); }
     1246
     1247        | comma_expression ';' TYPEDEFname                                      // CFA, array type
     1248                {
     1249                        SemanticError( yylloc, "Array interator is currently unimplemented." ); $$ = nullptr;
     1250                        $$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr );
     1251                }
    12191252
    12201253                // There is a S/R conflicit if ~ and -~ are factored out.
     
    13661399
    13671400exception_statement:
    1368         TRY compound_statement handler_clause
     1401        TRY compound_statement handler_clause                                   %prec THEN
    13691402                { $$ = new StatementNode( build_try( $2, $3, 0 ) ); }
    13701403        | TRY compound_statement finally_clause
     
    13891422handler_key:
    13901423        CATCH                                                                           { $$ = CatchStmt::Terminate; }
     1424        | RECOVER                                                                       { $$ = CatchStmt::Terminate; }
    13911425        | CATCHRESUME                                                           { $$ = CatchStmt::Resume; }
     1426        | FIXUP                                                                         { $$ = CatchStmt::Resume; }
    13921427        ;
    13931428
     
    17411776        ;
    17421777
    1743 enum_specifier_nobody:                                                                  // type specifier - {...}
    1744                 // Preclude SUE declarations in restricted scopes (see type_specifier_nobody)
    1745         basic_type_specifier
    1746         | sue_type_specifier_nobody
    1747         ;
    1748 
    17491778type_qualifier_list_opt:                                                                // GCC, used in asm_statement
    17501779        // empty
     
    17661795type_qualifier:
    17671796        type_qualifier_name
    1768         | attribute
     1797        | attribute                                                                                     // trick handles most atrribute locations
    17691798        ;
    17701799
     
    18741903        | AUTO_TYPE
    18751904                { $$ = DeclarationNode::newBuiltinType( DeclarationNode::AutoType ); }
     1905        | vtable
     1906        ;
     1907
     1908vtable_opt:
     1909        // empty
     1910                { $$ = nullptr; }
     1911        | vtable;
     1912        ;
     1913
     1914vtable:
     1915        VTABLE '(' type_list ')' default_opt
     1916                { SemanticError( yylloc, "vtable is currently unimplemented." ); $$ = nullptr; }
     1917        ;
     1918
     1919default_opt:
     1920        // empty
     1921                { $$ = nullptr; }
     1922        | DEFAULT
     1923                { SemanticError( yylloc, "vtable default is currently unimplemented." ); $$ = nullptr; }
    18761924        ;
    18771925
     
    20252073          '{' field_declaration_list_opt '}' type_parameters_opt
    20262074                { $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); }
    2027         | aggregate_key attribute_list_opt type_name
    2028                 {
    2029                         // for type_name can be a qualified type name S.T, in which case only the last name in the chain needs a typedef (other names in the chain should already have one)
    2030                         typedefTable.makeTypedef( *$3->type->leafName(), forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef
     2075        | aggregate_key attribute_list_opt TYPEDEFname          // unqualified type name
     2076                {
     2077                        typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef
    20312078                        forall = false;                                                         // reset
    20322079                }
    20332080          '{' field_declaration_list_opt '}' type_parameters_opt
    2034                 { $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $8, $6, true )->addQualifiers( $2 ); }
     2081                {
     2082                        DeclarationNode::newFromTypedef( $3 );
     2083                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     2084                }
     2085        | aggregate_key attribute_list_opt TYPEGENname          // unqualified type name
     2086                {
     2087                        typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef
     2088                        forall = false;                                                         // reset
     2089                }
     2090          '{' field_declaration_list_opt '}' type_parameters_opt
     2091                {
     2092                        DeclarationNode::newFromTypeGen( $3, nullptr );
     2093                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     2094                }
    20352095        | aggregate_type_nobody
    20362096        ;
     
    20692129
    20702130aggregate_data:
    2071         STRUCT
    2072                 { yyy = true; $$ = AggregateDecl::Struct; }
     2131        STRUCT vtable_opt
     2132                { $$ = AggregateDecl::Struct; }
    20732133        | UNION
    2074                 { yyy = true; $$ = AggregateDecl::Union; }
     2134                { $$ = AggregateDecl::Union; }
    20752135        | EXCEPTION                                                                                     // CFA
    2076                 // { yyy = true; $$ = AggregateDecl::Exception; }
    2077                 { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2136                { $$ = AggregateDecl::Exception; }
     2137          //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    20782138        ;
    20792139
    20802140aggregate_control:                                                                              // CFA
    20812141        MONITOR
    2082                 { yyy = true; $$ = AggregateDecl::Monitor; }
     2142                { $$ = AggregateDecl::Monitor; }
    20832143        | MUTEX STRUCT
    2084                 { yyy = true; $$ = AggregateDecl::Monitor; }
     2144                { $$ = AggregateDecl::Monitor; }
    20852145        | GENERATOR
    2086                 { yyy = true; $$ = AggregateDecl::Generator; }
     2146                { $$ = AggregateDecl::Generator; }
    20872147        | MUTEX GENERATOR
    20882148                { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    20892149        | COROUTINE
    2090                 { yyy = true; $$ = AggregateDecl::Coroutine; }
     2150                { $$ = AggregateDecl::Coroutine; }
    20912151        | MUTEX COROUTINE
    20922152                { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    20932153        | THREAD
    2094                 { yyy = true; $$ = AggregateDecl::Thread; }
     2154                { $$ = AggregateDecl::Thread; }
    20952155        | MUTEX THREAD
    20962156                { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     
    21882248        ;
    21892249
    2190 // Cannot use attribute_list_opt because of ambiguity with enum_specifier_nobody, which already parses attribute.
    2191 // Hence, only a single attribute is allowed after the "ENUM".
    21922250enum_type:                                                                                              // enum
    2193         ENUM attribute_opt '{' enumerator_list comma_opt '}'
     2251        ENUM attribute_list_opt '{' enumerator_list comma_opt '}'
    21942252                { $$ = DeclarationNode::newEnum( nullptr, $4, true )->addQualifiers( $2 ); }
    2195         | ENUM attribute_opt identifier
     2253        | ENUM attribute_list_opt identifier
    21962254                { typedefTable.makeTypedef( *$3 ); }
    21972255          '{' enumerator_list comma_opt '}'
    21982256                { $$ = DeclarationNode::newEnum( $3, $6, true )->addQualifiers( $2 ); }
    2199         | ENUM attribute_opt typedef                                            // enum cannot be generic
     2257        | ENUM attribute_list_opt typedef_name                          // unqualified type name
    22002258          '{' enumerator_list comma_opt '}'
    22012259                { $$ = DeclarationNode::newEnum( $3->name, $5, true )->addQualifiers( $2 ); }
    2202         | ENUM enum_specifier_nobody '{' enumerator_list comma_opt '}'
    2203                 // { $$ = DeclarationNode::newEnum( nullptr, $4, true ); }
    2204                 { SemanticError( yylloc, "Typed enumeration is currently unimplemented." ); $$ = nullptr; }
    2205         | ENUM enum_specifier_nobody declarator '{' enumerator_list comma_opt '}'
    2206                 // {
    2207                 //      typedefTable.makeTypedef( *$3->name );
    2208                 //      $$ = DeclarationNode::newEnum( nullptr, $5, true );
    2209                 // }
    2210                 { SemanticError( yylloc, "Typed enumeration is currently unimplemented." ); $$ = nullptr; }
     2260        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
     2261                {
     2262                        if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
     2263                        SemanticError( yylloc, "Typed enumeration is currently unimplemented." ); $$ = nullptr;
     2264                }
     2265        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt
     2266                {
     2267                        if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
     2268                        typedefTable.makeTypedef( *$6 );
     2269                }
     2270          '{' enumerator_list comma_opt '}'
     2271                {
     2272                        SemanticError( yylloc, "Typed enumeration is currently unimplemented." ); $$ = nullptr;
     2273                }
     2274        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt '{' enumerator_list comma_opt '}'
     2275                {
     2276                        if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
     2277                        typedefTable.makeTypedef( *$6->name );
     2278                        SemanticError( yylloc, "Typed enumeration is currently unimplemented." ); $$ = nullptr;
     2279                }
    22112280        | enum_type_nobody
    22122281        ;
    22132282
    22142283enum_type_nobody:                                                                               // enum - {...}
    2215         ENUM attribute_opt identifier
    2216                 {
    2217                         typedefTable.makeTypedef( *$3 );
    2218                         $$ = DeclarationNode::newEnum( $3, 0, false )->addQualifiers( $2 );
    2219                 }
    2220         | ENUM attribute_opt type_name                                          // enum cannot be generic
    2221                 {
    2222                         typedefTable.makeTypedef( *$3->type->symbolic.name );
    2223                         $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false )->addQualifiers( $2 );
    2224                 }
     2284        ENUM attribute_list_opt identifier
     2285                { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false )->addQualifiers( $2 ); }
     2286        | ENUM attribute_list_opt type_name                                     // qualified type name
     2287                { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false )->addQualifiers( $2 ); }
    22252288        ;
    22262289
     
    22282291        identifier_or_type_name enumerator_value_opt
    22292292                { $$ = DeclarationNode::newEnumConstant( $1, $2 ); }
     2293        | INLINE type_name
     2294                { $$ = DeclarationNode::newEnumConstant( new string("inline"), nullptr ); }
    22302295        | enumerator_list ',' identifier_or_type_name enumerator_value_opt
    22312296                { $$ = $1->appendList( DeclarationNode::newEnumConstant( $3, $4 ) ); }
     2297        | enumerator_list ',' INLINE type_name enumerator_value_opt
     2298                { $$ = $1->appendList( DeclarationNode::newEnumConstant( new string("inline"), nullptr ) ); }
    22322299        ;
    22332300
     
    22372304        // | '=' constant_expression
    22382305        //      { $$ = $2; }
    2239         | '=' initializer
     2306        | simple_assignment_operator initializer
    22402307                { $$ = $2->get_expression(); }                                  // FIX ME: enum only deals with constant_expression
    22412308        ;
     
    23652432        // empty
    23662433                { $$ = nullptr; }
    2367         | '=' initializer
    2368                 { $$ = $2; }
    2369         | '=' VOID
    2370                 { $$ = new InitializerNode( true ); }
    2371         | ATassign initializer
    2372                 { $$ = $2->set_maybeConstructed( false ); }
     2434        | simple_assignment_operator initializer        { $$ = $1 == OperKinds::Assign ? $2 : $2->set_maybeConstructed( false ); }
     2435        | '=' VOID                                                                      { $$ = new InitializerNode( true ); }
    23732436        ;
    23742437
     
    26262689
    26272690external_definition:
    2628         declaration
     2691        DIRECTIVE
     2692                { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); }
     2693        | declaration
    26292694        | external_function_definition
    26302695        | EXTENSION external_definition                                         // GCC, multiple __extension__ allowed, meaning unknown
     
    26342699                }
    26352700        | ASM '(' string_literal ')' ';'                                        // GCC, global assembler statement
    2636                 {
    2637                         $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) );
    2638                 }
     2701                { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); }
    26392702        | EXTERN STRINGliteral                                                          // C++-style linkage specifier
    26402703                {
     
    27822845        ;
    27832846
    2784 attribute_opt:
    2785         // empty
    2786                 { $$ = nullptr; }
    2787         | attribute
    2788         ;
    2789 
    27902847attribute:                                                                                              // GCC
    27912848        ATTRIBUTE '(' '(' attribute_name_list ')' ')'
     
    28492906// declaring an array of functions versus a pointer to an array of functions.
    28502907
     2908paren_identifier:
     2909        identifier
     2910                { $$ = DeclarationNode::newName( $1 ); }
     2911        | '(' paren_identifier ')'                                                      // redundant parenthesis
     2912                { $$ = $2; }
     2913        ;
     2914
    28512915variable_declarator:
    28522916        paren_identifier attribute_list_opt
     
    28592923        ;
    28602924
    2861 paren_identifier:
    2862         identifier
    2863                 { $$ = DeclarationNode::newName( $1 ); }
    2864         | '(' paren_identifier ')'                                                      // redundant parenthesis
    2865                 { $$ = $2; }
    2866         ;
    2867 
    28682925variable_ptr:
    28692926        ptrref_operator variable_declarator
     
    28712928        | ptrref_operator type_qualifier_list variable_declarator
    28722929                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    2873         | '(' variable_ptr ')' attribute_list_opt
    2874                 { $$ = $2->addQualifiers( $4 ); }                               // redundant parenthesis
     2930        | '(' variable_ptr ')' attribute_list_opt                       // redundant parenthesis
     2931                { $$ = $2->addQualifiers( $4 ); }
     2932        | '(' attribute_list variable_ptr ')' attribute_list_opt // redundant parenthesis
     2933                { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
    28752934        ;
    28762935
     
    28802939        | '(' variable_ptr ')' array_dimension
    28812940                { $$ = $2->addArray( $4 ); }
    2882         | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
     2941        | '(' attribute_list variable_ptr ')' array_dimension
     2942                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
     2943        | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
    28832944                { $$ = $2->addArray( $4 ); }
     2945        | '(' attribute_list variable_array ')' multi_array_dimension // redundant parenthesis
     2946                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    28842947        | '(' variable_array ')'                                                        // redundant parenthesis
    28852948                { $$ = $2; }
     2949        | '(' attribute_list variable_array ')'                         // redundant parenthesis
     2950                { $$ = $3->addQualifiers( $2 ); }
    28862951        ;
    28872952
     
    28892954        '(' variable_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    28902955                { $$ = $2->addParamList( $6 ); }
     2956        | '(' attribute_list variable_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     2957                { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
    28912958        | '(' variable_function ')'                                                     // redundant parenthesis
    28922959                { $$ = $2; }
     2960        | '(' attribute_list variable_function ')'                      // redundant parenthesis
     2961                { $$ = $3->addQualifiers( $2 ); }
    28932962        ;
    28942963
     
    29102979        | '(' function_ptr ')' '(' push parameter_type_list_opt pop ')'
    29112980                { $$ = $2->addParamList( $6 ); }
     2981        | '(' attribute_list function_ptr ')' '(' push parameter_type_list_opt pop ')'
     2982                { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
    29122983        | '(' function_no_ptr ')'                                                       // redundant parenthesis
    29132984                { $$ = $2; }
     2985        | '(' attribute_list function_no_ptr ')'                        // redundant parenthesis
     2986                { $$ = $3->addQualifiers( $2 ); }
    29142987        ;
    29152988
     
    29192992        | ptrref_operator type_qualifier_list function_declarator
    29202993                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    2921         | '(' function_ptr ')'
    2922                 { $$ = $2; }
     2994        | '(' function_ptr ')' attribute_list_opt
     2995                { $$ = $2->addQualifiers( $4 ); }
     2996        | '(' attribute_list function_ptr ')' attribute_list_opt
     2997                { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
    29232998        ;
    29242999
     
    29263001        '(' function_ptr ')' array_dimension
    29273002                { $$ = $2->addArray( $4 ); }
     3003        | '(' attribute_list function_ptr ')' array_dimension
     3004                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    29283005        | '(' function_array ')' multi_array_dimension          // redundant parenthesis
    29293006                { $$ = $2->addArray( $4 ); }
     3007        | '(' attribute_list function_array ')' multi_array_dimension // redundant parenthesis
     3008                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    29303009        | '(' function_array ')'                                                        // redundant parenthesis
    29313010                { $$ = $2; }
     3011        | '(' attribute_list function_array ')'                         // redundant parenthesis
     3012                { $$ = $3->addQualifiers( $2 ); }
    29323013        ;
    29333014
     
    29503031        | '(' KR_function_ptr ')' '(' push parameter_type_list_opt pop ')'
    29513032                { $$ = $2->addParamList( $6 ); }
     3033        | '(' attribute_list KR_function_ptr ')' '(' push parameter_type_list_opt pop ')'
     3034                { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
    29523035        | '(' KR_function_no_ptr ')'                                            // redundant parenthesis
    29533036                { $$ = $2; }
     3037        | '(' attribute_list KR_function_no_ptr ')'                     // redundant parenthesis
     3038                { $$ = $3->addQualifiers( $2 ); }
    29543039        ;
    29553040
     
    29613046        | '(' KR_function_ptr ')'
    29623047                { $$ = $2; }
     3048        | '(' attribute_list KR_function_ptr ')'
     3049                { $$ = $3->addQualifiers( $2 ); }
    29633050        ;
    29643051
     
    29663053        '(' KR_function_ptr ')' array_dimension
    29673054                { $$ = $2->addArray( $4 ); }
     3055        | '(' attribute_list KR_function_ptr ')' array_dimension
     3056                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    29683057        | '(' KR_function_array ')' multi_array_dimension       // redundant parenthesis
    29693058                { $$ = $2->addArray( $4 ); }
     3059        | '(' attribute_list KR_function_array ')' multi_array_dimension // redundant parenthesis
     3060                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    29703061        | '(' KR_function_array ')'                                                     // redundant parenthesis
    29713062                { $$ = $2; }
     3063        | '(' attribute_list KR_function_array ')'                      // redundant parenthesis
     3064                { $$ = $3->addQualifiers( $2 ); }
    29723065        ;
    29733066
     
    29813074// The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays
    29823075// and functions versus pointers to arrays and functions.
     3076
     3077paren_type:
     3078        typedef_name
     3079                {
     3080                        // hide type name in enclosing scope by variable name
     3081                        typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER, "ID" );
     3082                }
     3083        | '(' paren_type ')'
     3084                { $$ = $2; }
     3085        ;
    29833086
    29843087variable_type_redeclarator:
     
    29923095        ;
    29933096
    2994 paren_type:
    2995         typedef
    2996                 // hide type name in enclosing scope by variable name
    2997                 {
    2998                         // if ( ! typedefTable.existsCurr( *$1->name ) ) {
    2999                                 typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER, "ID" );
    3000                         // } else {
    3001                         //      SemanticError( yylloc, string("'") + *$1->name + "' redeclared as different kind of symbol." ); $$ = nullptr;
    3002                         // } // if
    3003                 }
    3004         | '(' paren_type ')'
    3005                 { $$ = $2; }
    3006         ;
    3007 
    30083097type_ptr:
    30093098        ptrref_operator variable_type_redeclarator
     
    30113100        | ptrref_operator type_qualifier_list variable_type_redeclarator
    30123101                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3013         | '(' type_ptr ')' attribute_list_opt
    3014                 { $$ = $2->addQualifiers( $4 ); }                               // redundant parenthesis
     3102        | '(' type_ptr ')' attribute_list_opt                           // redundant parenthesis
     3103                { $$ = $2->addQualifiers( $4 ); }
     3104        | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis
     3105                { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
    30153106        ;
    30163107
     
    30203111        | '(' type_ptr ')' array_dimension
    30213112                { $$ = $2->addArray( $4 ); }
     3113        | '(' attribute_list type_ptr ')' array_dimension
     3114                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    30223115        | '(' type_array ')' multi_array_dimension                      // redundant parenthesis
    30233116                { $$ = $2->addArray( $4 ); }
     3117        | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis
     3118                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    30243119        | '(' type_array ')'                                                            // redundant parenthesis
    30253120                { $$ = $2; }
     3121        | '(' attribute_list type_array ')'                                     // redundant parenthesis
     3122                { $$ = $3->addQualifiers( $2 ); }
    30263123        ;
    30273124
     
    30313128        | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    30323129                { $$ = $2->addParamList( $6 ); }
     3130        | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3131                { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
    30333132        | '(' type_function ')'                                                         // redundant parenthesis
    30343133                { $$ = $2; }
     3134        | '(' attribute_list type_function ')'                          // redundant parenthesis
     3135                { $$ = $3->addQualifiers( $2 ); }
    30353136        ;
    30363137
     
    30573158        | ptrref_operator type_qualifier_list identifier_parameter_declarator
    30583159                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3059         | '(' identifier_parameter_ptr ')' attribute_list_opt
     3160        | '(' identifier_parameter_ptr ')' attribute_list_opt // redundant parenthesis
    30603161                { $$ = $2->addQualifiers( $4 ); }
    30613162        ;
     
    30913192
    30923193type_parameter_redeclarator:
    3093         typedef attribute_list_opt
     3194        typedef_name attribute_list_opt
    30943195                { $$ = $1->addQualifiers( $2 ); }
    3095         | '&' MUTEX typedef attribute_list_opt
     3196        | '&' MUTEX typedef_name attribute_list_opt
    30963197                { $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( Type::Mutex ), OperKinds::AddressOf ) )->addQualifiers( $4 ); }
    30973198        | type_parameter_ptr
     
    31023203        ;
    31033204
    3104 typedef:
     3205typedef_name:
    31053206        TYPEDEFname
    31063207                { $$ = DeclarationNode::newName( $1 ); }
     
    31143215        | ptrref_operator type_qualifier_list type_parameter_redeclarator
    31153216                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3116         | '(' type_parameter_ptr ')' attribute_list_opt
     3217        | '(' type_parameter_ptr ')' attribute_list_opt         // redundant parenthesis
    31173218                { $$ = $2->addQualifiers( $4 ); }
    31183219        ;
    31193220
    31203221type_parameter_array:
    3121         typedef array_parameter_dimension
     3222        typedef_name array_parameter_dimension
    31223223                { $$ = $1->addArray( $2 ); }
    31233224        | '(' type_parameter_ptr ')' array_parameter_dimension
     
    31263227
    31273228type_parameter_function:
    3128         typedef '(' push parameter_type_list_opt pop ')'        // empty parameter list OBSOLESCENT (see 3)
     3229        typedef_name '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    31293230                { $$ = $1->addParamList( $4 ); }
    31303231        | '(' type_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     
    32553356        | ptrref_operator type_qualifier_list abstract_parameter_declarator
    32563357                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3257         | '(' abstract_parameter_ptr ')' attribute_list_opt
     3358        | '(' abstract_parameter_ptr ')' attribute_list_opt     // redundant parenthesis
    32583359                { $$ = $2->addQualifiers( $4 ); }
    32593360        ;
     
    33343435        | ptrref_operator type_qualifier_list variable_abstract_declarator
    33353436                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3336         | '(' variable_abstract_ptr ')' attribute_list_opt
     3437        | '(' variable_abstract_ptr ')' attribute_list_opt      // redundant parenthesis
    33373438                { $$ = $2->addQualifiers( $4 ); }
    33383439        ;
  • src/ResolvExpr/CurrentObject.cc

    rfeacef9 r5407cdc  
    925925                if ( auto aggr = dynamic_cast< const BaseInstType * >( type ) ) {
    926926                        if ( auto sit = dynamic_cast< const StructInstType * >( aggr ) ) {
     927                                assert( sit->base );
    927928                                return new StructIterator{ loc, sit };
    928929                        } else if ( auto uit = dynamic_cast< const UnionInstType * >( aggr ) ) {
     930                                assert( uit->base );
    929931                                return new UnionIterator{ loc, uit };
    930932                        } else {
  • src/SynTree/Constant.cc

    rfeacef9 r5407cdc  
    4242}
    4343
     44Constant Constant::from_string( const std::string & str ) {
     45        Type * charType = new BasicType( noQualifiers, BasicType::Char );
     46        // Adjust the length of the string for the terminator.
     47        Expression * strSize = new ConstantExpr( Constant::from_ulong( str.size() + 1 ) );
     48        Type * strType = new ArrayType( noQualifiers, charType, strSize, false, false );
     49        const std::string strValue = "\"" + str + "\"";
     50        return Constant( strType, strValue, std::nullopt );
     51}
     52
    4453Constant Constant::null( Type * ptrtype ) {
    4554        if ( nullptr == ptrtype ) {
  • src/SynTree/Constant.h

    rfeacef9 r5407cdc  
    4747        /// generates an integer constant of the given unsigned long int
    4848        static Constant from_ulong( unsigned long i );
     49        /// generates a string constant from the given string (char type, unquoted string)
     50        static Constant from_string( const std::string & string );
    4951
    5052        /// generates a null pointer value for the given type. void * if omitted.
  • src/SynTree/Declaration.cc

    rfeacef9 r5407cdc  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Dec 11 16:39:56 2019
    13 // Update Count     : 36
     12// Last Modified On : Fri Mar 12 18:35:39 2021
     13// Update Count     : 37
    1414//
    1515
     
    6666
    6767
     68DirectiveDecl::DirectiveDecl( DirectiveStmt *stmt ) : Declaration( "", Type::StorageClasses(), LinkageSpec::C ), stmt( stmt ) {
     69}
     70
     71DirectiveDecl::DirectiveDecl( const DirectiveDecl &other ) : Declaration( other ), stmt( maybeClone( other.stmt ) ) {
     72}
     73
     74DirectiveDecl::~DirectiveDecl() {
     75        delete stmt;
     76}
     77
     78void DirectiveDecl::print( std::ostream &os, Indenter indent ) const {
     79        stmt->print( os, indent );
     80}
     81
     82void DirectiveDecl::printShort( std::ostream &os, Indenter indent ) const {
     83        stmt->print( os, indent );
     84}
     85
     86
    6887StaticAssertDecl::StaticAssertDecl( Expression * condition, ConstantExpr * message ) : Declaration( "", Type::StorageClasses(), LinkageSpec::C ), condition( condition ), message( message )  {
    6988}
  • src/SynTree/Declaration.h

    rfeacef9 r5407cdc  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jan 11 20:48:39 2021
    13 // Update Count     : 158
     12// Last Modified On : Fri Mar 12 18:35:36 2021
     13// Update Count     : 159
    1414//
    1515
     
    400400};
    401401
     402class DirectiveDecl : public Declaration {
     403  public:
     404        DirectiveStmt * stmt;
     405
     406        DirectiveDecl( DirectiveStmt * stmt );
     407        DirectiveDecl( const DirectiveDecl & other );
     408        virtual ~DirectiveDecl();
     409
     410        DirectiveStmt * get_stmt() { return stmt; }
     411        void set_stmt( DirectiveStmt * newValue ) { stmt = newValue; }
     412
     413        virtual DirectiveDecl * clone() const override { return new DirectiveDecl( *this ); }
     414        virtual void accept( Visitor & v ) override { v.visit( this ); }
     415        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     416        virtual DirectiveDecl * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     417        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     418        virtual void printShort( std::ostream & os, Indenter indent = {} ) const override;
     419};
     420
    402421class StaticAssertDecl : public Declaration {
    403422public:
  • src/SynTree/Mutator.h

    rfeacef9 r5407cdc  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 25 22:37:46 2019
    13 // Update Count     : 17
     12// Last Modified On : Fri Mar 12 18:35:36 2021
     13// Update Count     : 18
    1414//
    1515#pragma once
     
    3434        virtual Declaration * mutate( TypedefDecl * typeDecl ) = 0;
    3535        virtual AsmDecl * mutate( AsmDecl * asmDecl ) = 0;
     36        virtual DirectiveDecl * mutate( DirectiveDecl * directiveDecl ) = 0;
    3637        virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) = 0;
    3738
  • src/SynTree/SynTree.h

    rfeacef9 r5407cdc  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 25 22:37:45 2019
    13 // Update Count     : 12
     12// Last Modified On : Fri Mar 12 18:56:44 2021
     13// Update Count     : 13
    1414//
    1515
     
    3636class TypedefDecl;
    3737class AsmDecl;
     38class DirectiveDecl;
    3839class StaticAssertDecl;
    3940
  • src/SynTree/Visitor.h

    rfeacef9 r5407cdc  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 25 22:21:49 2019
    13 // Update Count     : 14
     12// Last Modified On : Fri Mar 12 18:35:35 2021
     13// Update Count     : 15
    1414//
    1515
     
    4545        virtual void visit( AsmDecl * node ) { visit( const_cast<const AsmDecl *>(node) ); }
    4646        virtual void visit( const AsmDecl * asmDecl ) = 0;
     47        virtual void visit( DirectiveDecl * node ) { visit( const_cast<const DirectiveDecl *>(node) ); }
     48        virtual void visit( const DirectiveDecl * directiveDecl ) = 0;
    4749        virtual void visit( StaticAssertDecl * node ) { visit( const_cast<const StaticAssertDecl *>(node) ); }
    4850        virtual void visit( const StaticAssertDecl * assertDecl ) = 0;
  • src/Virtual/ExpandCasts.cc

    rfeacef9 r5407cdc  
    3232namespace Virtual {
    3333
     34static bool is_prefix( const std::string & prefix, const std::string& entire ) {
     35        size_t const p_size = prefix.size();
     36        return (p_size < entire.size() && prefix == entire.substr(0, p_size));
     37}
     38
     39static bool is_type_id_object( const ObjectDecl * objectDecl ) {
     40        const std::string & objectName = objectDecl->name;
     41        return is_prefix( "__cfatid_", objectName );
     42}
     43
    3444        // Indented until the new ast code gets added.
    3545
     
    6676        };
    6777
    68         /* Currently virtual depends on the rather brittle name matching between
    69          * a (strict/explicate) virtual type, its vtable type and the vtable
    70          * instance.
    71          * A stronger implementation, would probably keep track of those triads
    72          * and use that information to create better error messages.
    73          */
    74 
    75         namespace {
    76 
    77         std::string get_vtable_name( std::string const & name ) {
    78                 return name + "_vtable";
    79         }
    80 
    81         std::string get_vtable_inst_name( std::string const & name ) {
    82                 return std::string("_") + get_vtable_name( name ) + "_instance";
    83         }
    84 
    85         std::string get_vtable_name_root( std::string const & name ) {
    86                 return name.substr(0, name.size() - 7 );
    87         }
    88 
    89         std::string get_vtable_inst_name_root( std::string const & name ) {
    90                 return get_vtable_name_root( name.substr(1, name.size() - 10 ) );
    91         }
    92 
    93         bool is_vtable_inst_name( std::string const & name ) {
    94                 return 17 < name.size() &&
    95                         name == get_vtable_inst_name( get_vtable_inst_name_root( name ) );
    96         }
    97 
    98         } // namespace
    99 
    10078        class VirtualCastCore {
    101                 Type * pointer_to_pvt(int level_of_indirection) {
     79                CastExpr * cast_to_type_id( Expression * expr, int level_of_indirection ) {
    10280                        Type * type = new StructInstType(
    10381                                Type::Qualifiers( Type::Const ), pvt_decl );
     
    10583                                type = new PointerType( noQualifiers, type );
    10684                        }
    107                         return type;
     85                        return new CastExpr( expr, type );
    10886                }
    10987
     
    141119
    142120        void VirtualCastCore::premutate( ObjectDecl * objectDecl ) {
    143                 if ( is_vtable_inst_name( objectDecl->get_name() ) ) {
    144                         if ( ObjectDecl * existing = indexer.insert( objectDecl ) ) {
    145                                 std::string msg = "Repeated instance of virtual table, original found at: ";
    146                                 msg += existing->location.filename;
    147                                 msg += ":" + toString( existing->location.first_line );
    148                                 SemanticError( objectDecl->location, msg );
    149                         }
     121                if ( is_type_id_object( objectDecl ) ) {
     122                        // Multiple definitions should be fine because of linkonce.
     123                        indexer.insert( objectDecl );
    150124                }
    151125        }
     
    170144        }
    171145
    172         /// Get the virtual table type used in a virtual cast.
    173         Type * getVirtualTableType( const VirtualCastExpr * castExpr ) {
    174                 const Type * objectType;
    175                 if ( auto target = dynamic_cast<const PointerType *>( castExpr->result ) ) {
    176                         objectType = target->base;
    177                 } else if ( auto target = dynamic_cast<const ReferenceType *>( castExpr->result ) ) {
    178                         objectType = target->base;
     146        /// Get the base type from a pointer or reference.
     147        const Type * getBaseType( const Type * type ) {
     148                if ( auto target = dynamic_cast<const PointerType *>( type ) ) {
     149                        return target->base;
     150                } else if ( auto target = dynamic_cast<const ReferenceType *>( type ) ) {
     151                        return target->base;
    179152                } else {
    180                         castError( castExpr, "Virtual cast type must be a pointer or reference type." );
    181                 }
    182                 assert( objectType );
    183 
    184                 const StructInstType * structType = dynamic_cast<const StructInstType *>( objectType );
    185                 if ( nullptr == structType ) {
    186                         castError( castExpr, "Virtual cast type must refer to a structure type." );
    187                 }
    188                 const StructDecl * structDecl = structType->baseStruct;
    189                 assert( structDecl );
    190 
    191                 const ObjectDecl * fieldDecl = nullptr;
    192                 if ( 0 < structDecl->members.size() ) {
    193                         const Declaration * memberDecl = structDecl->members.front();
     153                        return nullptr;
     154                }
     155        }
     156
     157        /* Attempt to follow the "head" field of the structure to get the...
     158         * Returns nullptr on error, otherwise owner must free returned node.
     159         */
     160        StructInstType * followHeadPointerType(
     161                        const StructInstType * oldType,
     162                        const std::string& fieldName,
     163                        const CodeLocation& errorLocation ) {
     164
     165                // First section of the function is all about trying to fill this variable in.
     166                StructInstType * newType = nullptr;
     167                {
     168                        const StructDecl * oldDecl = oldType->baseStruct;
     169                        assert( oldDecl );
     170
     171                        // Helper function for throwing semantic errors.
     172                        auto throwError = [&fieldName, &errorLocation, &oldDecl](const std::string& message) {
     173                                const std::string& context = "While following head pointer of " +
     174                                        oldDecl->name + " named '" + fieldName + "': ";
     175                                SemanticError( errorLocation, context + message );
     176                        };
     177
     178                        if ( oldDecl->members.empty() ) {
     179                                throwError( "Type has no fields." );
     180                        }
     181                        const Declaration * memberDecl = oldDecl->members.front();
    194182                        assert( memberDecl );
    195                         fieldDecl = dynamic_cast<const ObjectDecl *>( memberDecl );
    196                         if ( fieldDecl && fieldDecl->name != "virtual_table" ) {
    197                                 fieldDecl = nullptr;
    198                         }
    199                 }
    200                 if ( nullptr == fieldDecl ) {
    201                         castError( castExpr, "Virtual cast type must have a leading virtual_table field." );
    202                 }
    203                 const PointerType * fieldType = dynamic_cast<const PointerType *>( fieldDecl->type );
    204                 if ( nullptr == fieldType ) {
    205                         castError( castExpr, "Virtual cast type virtual_table field is not a pointer." );
    206                 }
    207                 assert( fieldType->base );
    208                 auto virtualStructType = dynamic_cast<const StructInstType *>( fieldType->base );
    209                 assert( virtualStructType );
    210 
    211                 // Here is the type, but if it is polymorphic it will have lost information.
    212                 // (Always a clone so that it may always be deleted.)
    213                 StructInstType * virtualType = virtualStructType->clone();
    214                 if ( ! structType->parameters.empty() ) {
    215                         deleteAll( virtualType->parameters );
    216                         virtualType->parameters.clear();
    217                         cloneAll( structType->parameters, virtualType->parameters );
    218                 }
    219                 return virtualType;
     183                        const ObjectDecl * fieldDecl = dynamic_cast<const ObjectDecl *>( memberDecl );
     184                        assert( fieldDecl );
     185                        if ( fieldName != fieldDecl->name ) {
     186                                throwError( "Head field did not have expected name." );
     187                        }
     188
     189                        const Type * fieldType = fieldDecl->type;
     190                        if ( nullptr == fieldType ) {
     191                                throwError( "Could not get head field." );
     192                        }
     193                        const PointerType * ptrType = dynamic_cast<const PointerType *>( fieldType );
     194                        if ( nullptr == ptrType ) {
     195                                throwError( "First field is not a pointer type." );
     196                        }
     197                        assert( ptrType->base );
     198                        newType = dynamic_cast<StructInstType *>( ptrType->base );
     199                        if ( nullptr == newType ) {
     200                                throwError( "First field does not point to a structure type." );
     201                        }
     202                }
     203
     204                // Now we can look into copying it.
     205                newType = newType->clone();
     206                if ( ! oldType->parameters.empty() ) {
     207                        deleteAll( newType->parameters );
     208                        newType->parameters.clear();
     209                        cloneAll( oldType->parameters, newType->parameters );
     210                }
     211                return newType;
     212        }
     213
     214        /// Get the type-id type from a virtual type.
     215        StructInstType * getTypeIdType( const Type * type, const CodeLocation& errorLocation ) {
     216                const StructInstType * typeInst = dynamic_cast<const StructInstType *>( type );
     217                if ( nullptr == typeInst ) {
     218                        return nullptr;
     219                }
     220                StructInstType * tableInst =
     221                        followHeadPointerType( typeInst, "virtual_table", errorLocation );
     222                if ( nullptr == tableInst ) {
     223                        return nullptr;
     224                }
     225                StructInstType * typeIdInst =
     226                        followHeadPointerType( tableInst, "__cfavir_typeid", errorLocation );
     227                delete tableInst;
     228                return typeIdInst;
    220229        }
    221230
     
    228237                assert( pvt_decl );
    229238
    230                 const Type * vtable_type = getVirtualTableType( castExpr );
    231                 ObjectDecl * table = indexer.lookup( vtable_type );
    232                 if ( nullptr == table ) {
    233                         SemanticError( castLocation( castExpr ),
    234                                 "Could not find virtual table instance." );
     239                const Type * base_type = getBaseType( castExpr->result );
     240                if ( nullptr == base_type ) {
     241                        castError( castExpr, "Virtual cast target must be a pointer or reference type." );
     242                }
     243                const Type * type_id_type = getTypeIdType( base_type, castLocation( castExpr ) );
     244                if ( nullptr == type_id_type ) {
     245                        castError( castExpr, "Ill formed virtual cast target type." );
     246                }
     247                ObjectDecl * type_id = indexer.lookup( type_id_type );
     248                delete type_id_type;
     249                if ( nullptr == type_id ) {
     250                        castError( castExpr, "Virtual cast does not target a virtual type." );
    235251                }
    236252
    237253                Expression * result = new CastExpr(
    238254                        new ApplicationExpr( VariableExpr::functionPointer( vcast_decl ), {
    239                                         new CastExpr(
    240                                                 new AddressExpr( new VariableExpr( table ) ),
    241                                                 pointer_to_pvt(1)
    242                                         ),
    243                                         new CastExpr(
    244                                                 castExpr->get_arg(),
    245                                                 pointer_to_pvt(2)
    246                                         )
     255                                cast_to_type_id( new AddressExpr( new VariableExpr( type_id ) ), 1 ),
     256                                cast_to_type_id( castExpr->get_arg(), 2 ),
    247257                        } ),
    248258                        castExpr->get_result()->clone()
     
    252262                castExpr->set_result( nullptr );
    253263                delete castExpr;
    254                 delete vtable_type;
    255264                return result;
    256265        }
  • src/Virtual/Tables.cc

    rfeacef9 r5407cdc  
    1010// Created On       : Mon Aug 31 11:11:00 2020
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Sep  3 14:56:00 2020
    13 // Update Count     : 0
     12// Last Modified On : Wed Apr 21 15:36:00 2021
     13// Update Count     : 2
    1414//
    1515
     
    2222namespace Virtual {
    2323
     24std::string typeIdType( std::string const & type_name ) {
     25        return "__cfatid_struct_" + type_name;
     26}
     27
     28std::string typeIdName( std::string const & type_name ) {
     29        return "__cfatid_" + type_name;
     30}
     31
     32static std::string typeIdTypeToInstance( std::string const & type_name ) {
     33        return typeIdName(type_name.substr(16));
     34}
     35
    2436std::string vtableTypeName( std::string const & name ) {
    2537        return name + "_vtable";
    2638}
    2739
     40std::string baseTypeName( std::string const & vtable_type_name ) {
     41        return vtable_type_name.substr(0, vtable_type_name.size() - 7);
     42}
     43
    2844std::string instanceName( std::string const & name ) {
    2945        return std::string("_") + name + "_instance";
     
    3248std::string vtableInstanceName( std::string const & name ) {
    3349        return instanceName( vtableTypeName( name ) );
     50}
     51
     52std::string concurrentDefaultVTableName() {
     53        return "_default_vtable";
    3454}
    3555
     
    4161
    4262static ObjectDecl * makeVtableDeclaration(
     63                std::string const & name,
    4364                StructInstType * type, Initializer * init ) {
    44         std::string const & name = instanceName( type->name );
    4565        Type::StorageClasses storage = noStorageClasses;
    4666        if ( nullptr == init ) {
     
    5777}
    5878
    59 ObjectDecl * makeVtableForward( StructInstType * type ) {
     79ObjectDecl * makeVtableForward( std::string const & name, StructInstType * type ) {
    6080        assert( type );
    61         return makeVtableDeclaration( type, nullptr );
     81        return makeVtableDeclaration( name, type, nullptr );
    6282}
    6383
    6484ObjectDecl * makeVtableInstance(
    65                 StructInstType * vtableType, Type * objectType, Initializer * init ) {
     85                std::string const & name, StructInstType * vtableType,
     86                Type * objectType, Initializer * init ) {
    6687        assert( vtableType );
    6788        assert( objectType );
     
    81102                                inits.push_back(
    82103                                                new SingleInit( new AddressExpr( new NameExpr( parentInstance ) ) ) );
     104                        } else if ( std::string( "__cfavir_typeid" ) == field->name ) {
     105                                std::string const & baseType = baseTypeName( vtableType->name );
     106                                std::string const & typeId = typeIdName( baseType );
     107                                inits.push_back( new SingleInit( new AddressExpr( new NameExpr( typeId ) ) ) );
    83108                        } else if ( std::string( "size" ) == field->name ) {
    84109                                inits.push_back( new SingleInit( new SizeofExpr( objectType->clone() ) ) );
     
    95120                assert(false);
    96121        }
    97         return makeVtableDeclaration( vtableType, init );
     122        return makeVtableDeclaration( name, vtableType, init );
    98123}
    99124
     
    147172}
    148173
    149 }
     174Attribute * linkonce( const std::string & subsection ) {
     175        const std::string section = ".gnu.linkonce." + subsection;
     176        return new Attribute( "section", {
     177                new ConstantExpr( Constant::from_string( section ) ),
     178        } );
     179}
     180
     181ObjectDecl * makeTypeIdInstance( StructInstType const * typeIdType ) {
     182        assert( typeIdType );
     183        StructInstType * type = typeIdType->clone();
     184        type->tq.is_const = true;
     185        std::string const & typeid_name = typeIdTypeToInstance( typeIdType->name );
     186        return new ObjectDecl(
     187                typeid_name,
     188                noStorageClasses,
     189                LinkageSpec::Cforall,
     190                /* bitfieldWidth */ nullptr,
     191                type,
     192                new ListInit( { new SingleInit(
     193                        new AddressExpr( new NameExpr( "__cfatid_exception_t" ) )
     194                        ) } ),
     195                { linkonce( typeid_name ) },
     196                noFuncSpecifiers
     197        );
     198}
     199
     200}
  • src/Virtual/Tables.h

    rfeacef9 r5407cdc  
    1010// Created On       : Mon Aug 31 11:07:00 2020
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Sep  1 14:29:00 2020
    13 // Update Count     : 0
     12// Last Modified On : Wed Apr 21 10:30:00 2021
     13// Update Count     : 2
    1414//
    1515
     
    2222namespace Virtual {
    2323
     24std::string typeIdType( std::string const & type_name );
     25std::string typeIdName( std::string const & type_name );
    2426std::string vtableTypeName( std::string const & type_name );
    2527std::string instanceName( std::string const & vtable_name );
    2628std::string vtableInstanceName( std::string const & type_name );
     29std::string concurrentDefaultVTableName();
    2730bool isVTableInstanceName( std::string const & name );
    2831
    29 ObjectDecl * makeVtableForward( StructInstType * vtableType );
     32ObjectDecl * makeVtableForward(
     33        std::string const & name, StructInstType * vtableType );
    3034/* Create a forward declaration of a vtable of the given type.
    3135 * vtableType node is consumed.
    3236 */
    3337
    34 ObjectDecl * makeVtableInstance( StructInstType * vtableType, Type * objectType,
     38ObjectDecl * makeVtableInstance(
     39        std::string const & name,
     40        StructInstType * vtableType, Type * objectType,
    3541        Initializer * init = nullptr );
    3642/* Create an initialized definition of a vtable.
     
    5056 */
    5157
     58ObjectDecl * makeTypeIdInstance( StructInstType const * typeIdType );
     59/* Build an instance of the type-id from the type of the type-id.
     60 * TODO: Should take the parent type. Currently locked to the exception_t.
     61 */
     62
    5263}
  • src/main.cc

    rfeacef9 r5407cdc  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Feb  8 21:10:16 2021
    13 // Update Count     : 642
     12// Last Modified On : Sat Mar  6 15:49:00 2021
     13// Update Count     : 656
    1414//
    1515
     
    101101static string PreludeDirector = "";
    102102
    103 static void parse_cmdline( int argc, char *argv[] );
     103static void parse_cmdline( int argc, char * argv[] );
    104104static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit = false );
    105105static void dump( list< Declaration * > & translationUnit, ostream & out = cout );
     106static void dump( ast::TranslationUnit && transUnit, ostream & out = cout );
    106107
    107108static void backtrace( int start ) {                                    // skip first N stack frames
     
    158159#define SIGPARMS int sig __attribute__(( unused )), siginfo_t * sfp __attribute__(( unused )), ucontext_t * cxt __attribute__(( unused ))
    159160
    160 static void Signal( int sig, void (*handler)(SIGPARMS), int flags ) {
     161static void Signal( int sig, void (* handler)(SIGPARMS), int flags ) {
    161162        struct sigaction act;
    162163
     
    165166
    166167        if ( sigaction( sig, &act, nullptr ) == -1 ) {
    167             cerr << "*CFA runtime error* problem installing signal handler, error(" << errno << ") " << strerror( errno ) << endl;
     168            cerr << "*cfa-cpp compilation error* problem installing signal handler, error(" << errno << ") " << strerror( errno ) << endl;
    168169            _exit( EXIT_FAILURE );
    169170        } // if
     
    349350                        PASS( "Resolve", ResolvExpr::resolve( transUnit ) );
    350351                        if ( exprp ) {
    351                                 translationUnit = convert( move( transUnit ) );
    352                                 dump( translationUnit );
     352                                dump( move( transUnit ) );
    353353                                return EXIT_SUCCESS;
    354354                        } // if
     
    421421                        delete output;
    422422                } // if
    423         } catch ( SemanticErrorException &e ) {
     423        } catch ( SemanticErrorException & e ) {
    424424                if ( errorp ) {
    425425                        cerr << "---AST at error:---" << endl;
     
    432432                } // if
    433433                return EXIT_FAILURE;
    434         } catch ( UnimplementedError &e ) {
     434        } catch ( UnimplementedError & e ) {
    435435                cout << "Sorry, " << e.get_what() << " is not currently implemented" << endl;
    436436                if ( output != &cout ) {
     
    438438                } // if
    439439                return EXIT_FAILURE;
    440         } catch ( CompilerError &e ) {
     440        } catch ( CompilerError & e ) {
    441441                cerr << "Compiler Error: " << e.get_what() << endl;
    442442                cerr << "(please report bugs to [REDACTED])" << endl;
     
    445445                } // if
    446446                return EXIT_FAILURE;
     447        } catch ( std::bad_alloc & ) {
     448                cerr << "*cfa-cpp compilation error* std::bad_alloc" << endl;
     449                backtrace( 1 );
     450                abort();
    447451        } catch ( ... ) {
    448452                exception_ptr eptr = current_exception();
     
    451455                                rethrow_exception(eptr);
    452456                        } else {
    453                                 cerr << "Exception Uncaught and Unknown" << endl;
    454                         } // if
    455                 } catch(const exception& e) {
    456                         cerr << "Uncaught Exception \"" << e.what() << "\"\n";
     457                                cerr << "*cfa-cpp compilation error* exception uncaught and unknown" << endl;
     458                        } // if
     459                } catch( const exception & e ) {
     460                        cerr << "*cfa-cpp compilation error* uncaught exception \"" << e.what() << "\"\n";
    457461                } // try
    458462                return EXIT_FAILURE;
     
    544548enum { printoptsSize = sizeof( printopts ) / sizeof( printopts[0] ) };
    545549
    546 static void usage( char *argv[] ) {
     550static void usage( char * argv[] ) {
    547551    cout << "Usage: " << argv[0] << " [options] [input-file (default stdin)] [output-file (default stdout)], where options are:" << endl;
    548552        int i = 0, j = 1;                                                                       // j skips starting colon
     
    732736} // dump
    733737
     738static void dump( ast::TranslationUnit && transUnit, ostream & out ) {
     739        std::list< Declaration * > translationUnit = convert( move( transUnit ) );
     740        dump( translationUnit, out );
     741}
     742
    734743// Local Variables: //
    735744// tab-width: 4 //
Note: See TracChangeset for help on using the changeset viewer.