Changes in / [21255675:6a8882c]


Ignore:
Files:
1 deleted
26 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/kernel/fwd.hfa

    r21255675 r6a8882c  
    6565
    6666                extern uintptr_t __cfatls_get( unsigned long int member );
    67                 #define publicTLS_get( member ) ((typeof(__cfaabi_tls.member))__cfatls_get( __builtin_offsetof(KernelThreadData, member) ))
     67                // #define publicTLS_get( member ) ((typeof(__cfaabi_tls.member))__cfatls_get( __builtin_offsetof(KernelThreadData, member) ))
     68                #define publicTLS_get( member ) (__cfaabi_tls.member)
     69                // extern forall(otype T) T __cfatls_get( T * member, T value );
     70                // #define publicTLS_set( member, value ) __cfatls_set( (typeof(member)*)__builtin_offsetof(KernelThreadData, member), value );
    6871
    6972                static inline uint64_t __tls_rand() {
  • libcfa/src/concurrency/preemption.cfa

    r21255675 r6a8882c  
    231231}
    232232
    233 struct asm_region {
    234         void * before;
    235         void * after;
    236 };
    237 
    238 static inline bool __cfaasm_in( void * ip, struct asm_region & region ) {
    239         return ip >= region.before && ip <= region.after;
    240 }
    241 
    242 
    243233//----------
    244234// Get data from the TLS block
    245 // struct asm_region __cfaasm_get;
    246235uintptr_t __cfatls_get( unsigned long int offset ) __attribute__((__noinline__)); //no inline to avoid problems
    247236uintptr_t __cfatls_get( unsigned long int offset ) {
    248         // __cfaasm_get.before = ({ void * value; asm("movq $__cfaasm_get_before, %[v]\n\t" : [v]"=r"(value) ); value; });
    249         // __cfaasm_get.after  = ({ void * value; asm("movq $__cfaasm_get_after , %[v]\n\t" : [v]"=r"(value) ); value; });
    250237        // create a assembler label before
    251238        // marked as clobber all to avoid movement
     
    266253                // create a assembler label before
    267254                // marked as clobber all to avoid movement
    268                 asm volatile("__cfaasm_dsable_before:":::"memory");
     255                asm volatile("__cfaasm_disable_before:":::"memory");
    269256
    270257                with( __cfaabi_tls.preemption_state ) {
     
    288275                // create a assembler label after
    289276                // marked as clobber all to avoid movement
    290                 asm volatile("__cfaasm_dsable_after:":::"memory");
     277                asm volatile("__cfaasm_disable_after:":::"memory");
    291278        }
    292279
     
    296283                // create a assembler label before
    297284                // marked as clobber all to avoid movement
    298                 asm volatile("__cfaasm_enble_before:":::"memory");
     285                asm volatile("__cfaasm_enable_before:":::"memory");
    299286
    300287                processor   * proc = __cfaabi_tls.this_processor; // Cache the processor now since interrupts can start happening after the atomic store
     
    331318                // create a assembler label after
    332319                // marked as clobber all to avoid movement
    333                 asm volatile("__cfaasm_enble_after:":::"memory");
     320                asm volatile("__cfaasm_enable_after:":::"memory");
    334321        }
    335322
     
    399386}
    400387
    401 //-----------------------------------------------------------------------------
    402 // Some assembly required
    403 #if defined( __i386 )
    404         #ifdef __PIC__
    405                 #define RELOC_PRELUDE( label ) \
    406                         "calll   .Lcfaasm_prelude_" #label "$pb\n\t" \
    407                         ".Lcfaasm_prelude_" #label "$pb:\n\t" \
    408                         "popl    %%eax\n\t" \
    409                         ".Lcfaasm_prelude_" #label "_end:\n\t" \
    410                         "addl    $_GLOBAL_OFFSET_TABLE_+(.Lcfaasm_prelude_" #label "_end-.Lcfaasm_prelude_" #label "$pb), %%eax\n\t"
    411                 #define RELOC_PREFIX ""
    412                 #define RELOC_SUFFIX "@GOT(%%eax)"
    413         #else
    414                 #define RELOC_PREFIX "$"
    415                 #define RELOC_SUFFIX ""
    416         #endif
    417         #define __cfaasm_label( label ) static struct asm_region label = \
    418                 ({ \
    419                         struct asm_region region; \
    420                         asm( \
    421                                 RELOC_PRELUDE( label ) \
    422                                 "movl " RELOC_PREFIX "__cfaasm_" #label "_before" RELOC_SUFFIX ", %[vb]\n\t" \
    423                                 "movl " RELOC_PREFIX "__cfaasm_" #label "_after"  RELOC_SUFFIX ", %[va]\n\t" \
    424                                  : [vb]"=r"(region.before), [va]"=r"(region.after) \
    425                         ); \
    426                         region; \
    427                 });
    428 #elif defined( __x86_64 )
    429         #ifdef __PIC__
    430                 #define RELOC_PREFIX ""
    431                 #define RELOC_SUFFIX "@GOTPCREL(%%rip)"
    432         #else
    433                 #define RELOC_PREFIX "$"
    434                 #define RELOC_SUFFIX ""
    435         #endif
    436         #define __cfaasm_label( label ) static struct asm_region label = \
    437                 ({ \
    438                         struct asm_region region; \
    439                         asm( \
    440                                 "movq " RELOC_PREFIX "__cfaasm_" #label "_before" RELOC_SUFFIX ", %[vb]\n\t" \
    441                                 "movq " RELOC_PREFIX "__cfaasm_" #label "_after"  RELOC_SUFFIX ", %[va]\n\t" \
    442                                  : [vb]"=r"(region.before), [va]"=r"(region.after) \
    443                         ); \
    444                         region; \
    445                 });
    446 #elif defined( __aarch64__ )
    447         #ifdef __PIC__
    448                 #define RELOC_TAG "@PLT"
    449         #else
    450                 #define RELOC_TAG ""
    451         #endif
    452         #define __cfaasm_label( label ) \
    453                 ({ \
    454                         struct asm_region region; \
    455                         asm( \
    456                                 "mov %[vb], __cfaasm_" #label "_before@GOTPCREL(%%rip)"  "\n\t" \
    457                                 "mov %[va], __cfaasm_" #label "_after@GOTPCREL(%%rip)"   "\n\t" \
    458                                  : [vb]"=r"(region.before), [va]"=r"(region.after) \
    459                         ); \
    460                         region; \
    461                 });
    462 #else
    463         #error unknown hardware architecture
    464 #endif
    465 
    466388// KERNEL ONLY
    467389// Check if a __cfactx_switch signal handler shoud defer
    468390// If true  : preemption is safe
    469391// If false : preemption is unsafe and marked as pending
    470 static inline bool preemption_ready( void * ip ) {
    471         // Get all the region for which it is not safe to preempt
    472         __cfaasm_label( get    );
    473         __cfaasm_label( check  );
    474         __cfaasm_label( dsable );
    475         __cfaasm_label( enble );
    476         __cfaasm_label( nopoll );
    477 
     392static inline bool preemption_ready() {
    478393        // Check if preemption is safe
    479         bool ready = true;
    480         if( __cfaasm_in( ip, get    ) ) { ready = false; goto EXIT; };
    481         if( __cfaasm_in( ip, check  ) ) { ready = false; goto EXIT; };
    482         if( __cfaasm_in( ip, dsable ) ) { ready = false; goto EXIT; };
    483         if( __cfaasm_in( ip, enble  ) ) { ready = false; goto EXIT; };
    484         if( __cfaasm_in( ip, nopoll ) ) { ready = false; goto EXIT; };
    485         if( !__cfaabi_tls.preemption_state.enabled) { ready = false; goto EXIT; };
    486         if( __cfaabi_tls.preemption_state.in_progress ) { ready = false; goto EXIT; };
    487 
    488 EXIT:
     394        bool ready = __cfaabi_tls.preemption_state.enabled && ! __cfaabi_tls.preemption_state.in_progress;
     395
    489396        // Adjust the pending flag accordingly
    490397        __cfaabi_tls.this_processor->pending_preemption = !ready;
     
    561468// Kernel Signal Handlers
    562469//=============================================================================================
     470struct asm_region {
     471        void * before;
     472        void * after;
     473};
     474
     475//-----------------------------------------------------------------------------
     476// Some assembly required
     477#if defined( __i386 )
     478        #define __cfaasm_label( label ) \
     479                ({ \
     480                        struct asm_region region; \
     481                        asm( \
     482                                "movl $__cfaasm_" #label "_before, %[vb]\n\t" \
     483                                "movl $__cfaasm_" #label "_after , %[va]\n\t" \
     484                                 : [vb]"=r"(region.before), [vb]"=r"(region.before) \
     485                        ); \
     486                        region; \
     487                });
     488#elif defined( __x86_64 )
     489        #ifdef __PIC__
     490                #define PLT "@PLT"
     491        #else
     492                #define PLT ""
     493        #endif
     494        #define __cfaasm_label( label ) \
     495                ({ \
     496                        struct asm_region region; \
     497                        asm( \
     498                                "movq $__cfaasm_" #label "_before" PLT ", %[vb]\n\t" \
     499                                "movq $__cfaasm_" #label "_after"  PLT ", %[va]\n\t" \
     500                                 : [vb]"=r"(region.before), [va]"=r"(region.after) \
     501                        ); \
     502                        region; \
     503                });
     504#elif defined( __aarch64__ )
     505        #error __cfaasm_label undefined for arm
     506#else
     507        #error unknown hardware architecture
     508#endif
     509
    563510__cfaabi_dbg_debug_do( static thread_local void * last_interrupt = 0; )
    564511
     
    583530
    584531        // Check if it is safe to preempt here
    585         if( !preemption_ready( ip ) ) { return; }
     532        if( !preemption_ready() ) { return; }
     533
     534        struct asm_region region;
     535        region = __cfaasm_label( get     ); if( ip >= region.before && ip <= region.after ) return;
     536        region = __cfaasm_label( check   ); if( ip >= region.before && ip <= region.after ) return;
     537        region = __cfaasm_label( disable ); if( ip >= region.before && ip <= region.after ) return;
     538        region = __cfaasm_label( enable  ); if( ip >= region.before && ip <= region.after ) return;
     539        region = __cfaasm_label( nopoll  ); if( ip >= region.before && ip <= region.after ) return;
    586540
    587541        __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p @ %p).\n", __cfaabi_tls.this_processor, __cfaabi_tls.this_thread, (void *)(cxt->uc_mcontext.CFA_REG_IP) );
  • libcfa/src/stdlib.hfa

    r21255675 r6a8882c  
    101101                return (T *)pvalloc( sizeof(T) );                               // C pvalloc
    102102        } // pvalloc
    103 
    104         void free( T * addr ) {
    105                 free( (void *) addr );                                                  // C free
    106         } // free
    107 } // distribution
    108 
    109 static inline forall( ttype TT | { void free( TT ); } ) {
    110         // T* does not take void* and vice-versa
    111 
    112         void free( void * addr, TT rest ) {
    113                 free( addr );
    114                 free( rest );
    115         } // free
    116 
    117         forall( dtype T | sized(T) )
    118         void free( T * addr, TT rest ) {
    119                 free( addr );
    120                 free( rest );
    121         } // free
    122103} // distribution
    123104
     
    129110                forall( dtype T | sized(T) ) {
    130111                        union  U_fill           { char c; T * a; T t; };
    131                         struct S_fill           { char tag; U_fill(T) fill; };
     112                        struct S_fill           { char tag; char c; size_t size; T * at; char t[50]; };
    132113                        struct S_realloc        { inline T *; };
    133114                }
  • src/AST/Convert.cpp

    r21255675 r6a8882c  
    27642764                        old->location,
    27652765                        GET_ACCEPT_1(value, Expr),
    2766                         (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::NoConstruct
     2766                        (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::DoConstruct
    27672767                );
    27682768        }
     
    27732773                        GET_ACCEPT_V(initializers, Init),
    27742774                        GET_ACCEPT_V(designations, Designation),
    2775                         (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::NoConstruct
     2775                        (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::DoConstruct
    27762776                );
    27772777        }
  • src/AST/Decl.hpp

    r21255675 r6a8882c  
    7979        ptr<Expr> asmName;
    8080        bool isDeleted = false;
    81         bool isTypeFixed = false;
    8281
    8382        DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
  • src/AST/Init.hpp

    r21255675 r6a8882c  
    5050
    5151/// Flag for whether to construct from initialzier
    52 enum ConstructFlag { NoConstruct, MaybeConstruct };
     52enum ConstructFlag { DoConstruct, MaybeConstruct };
    5353
    5454/// Object initializer base class
     
    7171        ptr<Expr> value;
    7272
    73         SingleInit( const CodeLocation & loc, const Expr * val, ConstructFlag mc = NoConstruct )
     73        SingleInit( const CodeLocation & loc, const Expr * val, ConstructFlag mc = DoConstruct )
    7474        : Init( loc, mc ), value( val ) {}
    7575
     
    9090
    9191        ListInit( const CodeLocation & loc, std::vector<ptr<Init>> && is,
    92                 std::vector<ptr<Designation>> && ds = {}, ConstructFlag mc = NoConstruct );
     92                std::vector<ptr<Designation>> && ds = {}, ConstructFlag mc = DoConstruct );
    9393
    9494        using iterator = std::vector<ptr<Init>>::iterator;
     
    118118        ConstructorInit(
    119119                const CodeLocation & loc, const Stmt * ctor, const Stmt * dtor, const Init * init )
    120         : Init( loc, MaybeConstruct ), ctor( ctor ), dtor( dtor ), init( init ) {}
     120        : Init( loc, DoConstruct ), ctor( ctor ), dtor( dtor ), init( init ) {}
    121121
    122122        const Init * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/AST/Pass.impl.hpp

    r21255675 r6a8882c  
    423423                }
    424424                catch( SemanticErrorException &e ) {
    425                         if (__pass::on_error (visitor.core, *i, 0))
    426                                 errors.append( e );
     425                        errors.append( e );
    427426                }
    428427
     
    684683                // Do not enter (or leave) a new scope if atFunctionTop. Remember to save the result.
    685684                auto guard1 = makeFuncGuard( [this, enterScope = !this->atFunctionTop]() {
    686                         if ( enterScope ) {
    687                                 __pass::symtab::enter(core, 0);
    688                                 __pass::scope::enter(core, 0);
    689                         }
     685                        if ( enterScope ) __pass::symtab::enter(core, 0);
    690686                }, [this, leaveScope = !this->atFunctionTop]() {
    691                         if ( leaveScope ) {
    692                                 __pass::symtab::leave(core, 0);
    693                                 __pass::scope::leave(core, 0);
    694                         }
     687                        if ( leaveScope ) __pass::symtab::leave(core, 0);
    695688                });
    696689                ValueGuard< bool > guard2( atFunctionTop );
  • src/AST/Pass.proto.hpp

    r21255675 r6a8882c  
    266266        static void endTrace(core_t &, long) {}
    267267
    268         // Allows visitor to handle an error on top-level declarations, and possibly suppress the error.
    269         // If onError() returns false, the error will be ignored. By default, it returns true.
    270 
    271         template< typename core_t >
    272         static bool on_error (core_t &, ptr<Decl> &, long) { return true; }
    273 
    274         template< typename core_t >
    275         static auto on_error (core_t & core, ptr<Decl> & decl, int) -> decltype(core.on_error(decl)) {
    276                 return core.on_error(decl);
    277         }
    278 
    279268        // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement.
    280269        // All passes which have such functions are assumed desire this behaviour
  • src/AST/Type.cpp

    r21255675 r6a8882c  
    211211        for ( const Type * ty : types ) {
    212212                members.emplace_back( new ObjectDecl{
    213                         CodeLocation{}, "", ty, new ListInit( CodeLocation{}, {}, {}, NoConstruct ),
     213                        CodeLocation{}, "", ty, new ListInit( CodeLocation{}, {}, {}, MaybeConstruct ),
    214214                        Storage::Classes{}, Linkage::Cforall } );
    215215        }
  • src/CodeGen/CodeGenerator.cc

    r21255675 r6a8882c  
    120120                // GCC builtins should always be printed unmangled
    121121                if ( options.pretty || decl->linkage.is_gcc_builtin ) return decl->name;
    122                 if ( LinkageSpec::isMangled(decl->linkage) && decl->mangleName != "" ) {
     122                if ( decl->mangleName != "" ) {
    123123                        // need to incorporate scope level in order to differentiate names for destructors
    124124                        return decl->get_scopedMangleName();
  • src/CodeGen/FixMain.cc

    r21255675 r6a8882c  
    2626#include "SynTree/Declaration.h"   // for FunctionDecl, operator<<
    2727#include "SynTree/Type.h"          // for FunctionType
    28 #include "SymTab/Mangler.h"
    2928
    3029namespace CodeGen {
     
    4847                if( main_signature ) {
    4948                        os << "static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return ";
    50                         main_signature->mangleName = SymTab::Mangler::mangle(main_signature.get());
    5149
    5250                        os << main_signature->get_scopedMangleName() << "(";
  • src/CodeGen/FixNames.cc

    r21255675 r6a8882c  
    3131#include "SynTree/Type.h"          // for Type, BasicType, Type::Qualifiers
    3232#include "SynTree/Visitor.h"       // for Visitor, acceptAll
    33 #include "CompilationState.h"
    3433
    3534namespace CodeGen {
     
    103102                if ( dwt->get_name() != "" ) {
    104103                        if ( LinkageSpec::isMangled( dwt->get_linkage() ) ) {
    105                                 if (!useNewAST) {
    106                                         dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) );
    107                                 }
     104                                dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) );
    108105                                dwt->set_scopeLevel( scopeLevel );
    109106                        } // if
  • src/InitTweak/GenInit.cc

    r21255675 r6a8882c  
    2626#include "AST/Node.hpp"
    2727#include "AST/Stmt.hpp"
    28 #include "CompilationState.h"
    2928#include "CodeGen/OperatorTable.h"
    3029#include "Common/PassVisitor.h"        // for PassVisitor, WithGuards, WithShort...
     
    123122
    124123        void genInit( std::list< Declaration * > & translationUnit ) {
     124                fixReturnStatements( translationUnit );
    125125                HoistArrayDimension::hoistArrayDimension( translationUnit );
    126                 fixReturnStatements( translationUnit );
    127 
    128                 if (!useNewAST) {
    129                         CtorDtor::generateCtorDtor( translationUnit );
    130                 }
     126                CtorDtor::generateCtorDtor( translationUnit );
    131127        }
    132128
     
    196192
    197193                        // need to resolve array dimensions in order to accurately determine if constexpr
    198                         if (!useNewAST) {
    199                                 ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer );
    200                                 // array is variable-length when the dimension is not constexpr
    201                                 arrayType->isVarLen = ! isConstExpr( arrayType->dimension );
    202                         }
     194                        ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer );
     195                        // array is variable-length when the dimension is not constexpr
     196                        arrayType->isVarLen = ! isConstExpr( arrayType->dimension );
    203197                        // don't need to hoist dimension if it's definitely pure - only need to if there's potential for side effects.
    204                         // xxx - hoisting has no side effects anyways, so don't skip since we delay resolve     
    205                         // only skip in the most trivial case, which does not require resolve
    206                         if (dynamic_cast<ConstantExpr *>(arrayType->dimension)) return;
    207                         // if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return;
     198                        if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return;
    208199
    209200                        ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, Validate::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );
     
    254245        }
    255246
    256         // why is this not just on FunctionDecl?
    257247        void ManagedTypes::handleDWT( DeclarationWithType * dwt ) {
    258248                // if this function is a user-defined constructor or destructor, mark down the type as "managed"
     
    284274        void ManagedTypes::beginScope() { managedTypes.beginScope(); }
    285275        void ManagedTypes::endScope() { managedTypes.endScope(); }
    286 
    287         bool ManagedTypes_new::isManaged( const ast::Type * type ) const {
    288                 // references are never constructed
    289                 if ( dynamic_cast< const ast::ReferenceType * >( type ) ) return false;
    290                 if ( auto tupleType = dynamic_cast< const ast::TupleType * > ( type ) ) {
    291                         // tuple is also managed if any of its components are managed
    292                         for (auto & component : tupleType->types) {
    293                                 if (isManaged(component)) return true;
    294                         }
    295                 }
    296                 // need to clear and reset qualifiers when determining if a type is managed
    297                 // ValueGuard< Type::Qualifiers > qualifiers( type->get_qualifiers() );
    298                 auto tmp = shallowCopy(type);
    299                 tmp->qualifiers = {};
    300                 // delete tmp at return
    301                 ast::ptr<ast::Type> guard = tmp;
    302                 // a type is managed if it appears in the map of known managed types, or if it contains any polymorphism (is a type variable or generic type containing a type variable)
    303                 return managedTypes.find( Mangle::mangle( tmp, {Mangle::NoOverrideable | Mangle::NoGenericParams | Mangle::Type} ) ) != managedTypes.end() || GenPoly::isPolyType( tmp );
    304         }
    305 
    306         bool ManagedTypes_new::isManaged( const ast::ObjectDecl * objDecl ) const {
    307                 const ast::Type * type = objDecl->type;
    308                 while ( auto at = dynamic_cast< const ast::ArrayType * >( type ) ) {
    309                         // must always construct VLAs with an initializer, since this is an error in C
    310                         if ( at->isVarLen && objDecl->init ) return true;
    311                         type = at->base;
    312                 }
    313                 return isManaged( type );
    314         }
    315 
    316         void ManagedTypes_new::handleDWT( const ast::DeclWithType * dwt ) {
    317                 // if this function is a user-defined constructor or destructor, mark down the type as "managed"
    318                 if ( ! dwt->linkage.is_overrideable && CodeGen::isCtorDtor( dwt->name ) ) {
    319                         auto & params = GenPoly::getFunctionType( dwt->get_type())->params;
    320                         assert( ! params.empty() );
    321                         // Type * type = InitTweak::getPointerBase( params.front() );
    322                         // assert( type );
    323                         managedTypes.insert( Mangle::mangle( params.front(), {Mangle::NoOverrideable | Mangle::NoGenericParams | Mangle::Type} ) );
    324                 }
    325         }
    326 
    327         void ManagedTypes_new::handleStruct( const ast::StructDecl * aggregateDecl ) {
    328                 // don't construct members, but need to take note if there is a managed member,
    329                 // because that means that this type is also managed
    330                 for ( auto & member : aggregateDecl->members ) {
    331                         if ( auto field = member.as<ast::ObjectDecl>() ) {
    332                                 if ( isManaged( field ) ) {
    333                                         // generic parameters should not play a role in determining whether a generic type is constructed - construct all generic types, so that
    334                                         // polymorphic constructors make generic types managed types
    335                                         ast::StructInstType inst( aggregateDecl );
    336                                         managedTypes.insert( Mangle::mangle( &inst, {Mangle::NoOverrideable | Mangle::NoGenericParams | Mangle::Type} ) );
    337                                         break;
    338                                 }
    339                         }
    340                 }
    341         }
    342 
    343         void ManagedTypes_new::beginScope() { managedTypes.beginScope(); }
    344         void ManagedTypes_new::endScope() { managedTypes.endScope(); }
    345276
    346277        ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg ) {
     
    439370        // constructable object
    440371        InitExpander_new srcParam{ objDecl->init }, nullParam{ (const ast::Init *)nullptr };
    441         ast::ptr< ast::Expr > dstParam = new ast::VariableExpr(loc, objDecl);
    442372       
    443373        ast::ptr< ast::Stmt > ctor = SymTab::genImplicitCall(
    444                 srcParam, dstParam, loc, "?{}", objDecl );
     374                srcParam, new ast::VariableExpr{ loc, objDecl }, loc, "?{}", objDecl );
    445375        ast::ptr< ast::Stmt > dtor = SymTab::genImplicitCall(
    446                 nullParam, dstParam, loc, "^?{}", objDecl,
     376                nullParam, new ast::VariableExpr{ loc, objDecl }, loc, "^?{}", objDecl,
    447377                SymTab::LoopBackward );
    448378       
  • src/InitTweak/GenInit.h

    r21255675 r6a8882c  
    5252                GenPoly::ScopedSet< std::string > managedTypes;
    5353        };
    54 
    55         class ManagedTypes_new {
    56         public:
    57                 bool isManaged( const ast::ObjectDecl * objDecl ) const ; // determine if object is managed
    58                 bool isManaged( const ast::Type * type ) const; // determine if type is managed
    59 
    60                 void handleDWT( const ast::DeclWithType * dwt ); // add type to managed if ctor/dtor
    61                 void handleStruct( const ast::StructDecl * aggregateDecl ); // add type to managed if child is managed
    62 
    63                 void beginScope();
    64                 void endScope();
    65         private:
    66                 GenPoly::ScopedSet< std::string > managedTypes;
    67         };
    6854} // namespace
    6955
  • src/InitTweak/InitTweak.cc

    r21255675 r6a8882c  
    8787                };
    8888
    89                 struct HasDesignations_new : public ast::WithShortCircuiting {
    90                         bool result = false;
    91 
    92                         void previsit( const ast::Node * ) {
    93                                 // short circuit if we already know there are designations
    94                                 if ( result ) visit_children = false;
    95                         }
    96 
    97                         void previsit( const ast::Designation * des ) {
    98                                 // short circuit if we already know there are designations
    99                                 if ( result ) visit_children = false;
    100                                 else if ( ! des->designators.empty() ) {
    101                                         result = true;
    102                                         visit_children = false;
    103                                 }
    104                         }
    105                 };
    106 
    107                 struct InitDepthChecker_new : public ast::WithGuards {
    108                         bool result = true;
    109                         const ast::Type * type;
    110                         int curDepth = 0, maxDepth = 0;
    111                         InitDepthChecker_new( const ast::Type * type ) : type( type ) {
    112                                 const ast::Type * t = type;
    113                                 while ( auto at = dynamic_cast< const ast::ArrayType * >( t ) ) {
    114                                         maxDepth++;
    115                                         t = at->base;
    116                                 }
    117                                 maxDepth++;
    118                         }
    119                         void previsit( ListInit * ) {
    120                                 curDepth++;
    121                                 GuardAction( [this]() { curDepth--; } );
    122                                 if ( curDepth > maxDepth ) result = false;
    123                         }
    124                 };
    125 
    12689                struct InitFlattener_old : public WithShortCircuiting {
    12790                        void previsit( SingleInit * singleInit ) {
     
    159122                maybeAccept( objDecl->init, checker );
    160123                return checker.pass.depthOkay;
    161         }
    162 
    163         bool isDesignated( const ast::Init * init ) {
    164                 ast::Pass<HasDesignations_new> finder;
    165                 maybe_accept( init, finder );
    166                 return finder.core.result;
    167         }
    168 
    169         bool checkInitDepth( const ast::ObjectDecl * objDecl ) {
    170                 ast::Pass<InitDepthChecker_new> checker( objDecl->type );
    171                 maybe_accept( objDecl->init.get(), checker );
    172                 return checker.core.result;
    173124        }
    174125
     
    407358                        if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) {
    408359                                for ( const ast::Init * init : *listInit ) {
    409                                         buildCallExpr( shallowCopy(callExpr), index, dimension, init, out );
     360                                        buildCallExpr( callExpr, index, dimension, init, out );
    410361                                }
    411362                        } else {
    412                                 buildCallExpr( shallowCopy(callExpr), index, dimension, init, out );
     363                                buildCallExpr( callExpr, index, dimension, init, out );
    413364                        }
    414365                } else {
     
    10761027        };
    10771028
    1078         struct ConstExprChecker_new : public ast::WithShortCircuiting {
    1079                 // most expressions are not const expr
    1080                 void previsit( const ast::Expr * ) { result = false; visit_children = false; }
    1081 
    1082                 void previsit( const ast::AddressExpr *addressExpr ) {
    1083                         visit_children = false;
    1084                         const ast::Expr * arg = addressExpr->arg;
    1085 
    1086                         // address of a variable or member expression is constexpr
    1087                         if ( ! dynamic_cast< const ast::NameExpr * >( arg )
    1088                         && ! dynamic_cast< const ast::VariableExpr * >( arg )
    1089                         && ! dynamic_cast< const ast::MemberExpr * >( arg )
    1090                         && ! dynamic_cast< const ast::UntypedMemberExpr * >( arg ) ) result = false;
    1091                 }
    1092 
    1093                 // these expressions may be const expr, depending on their children
    1094                 void previsit( const ast::SizeofExpr * ) {}
    1095                 void previsit( const ast::AlignofExpr * ) {}
    1096                 void previsit( const ast::UntypedOffsetofExpr * ) {}
    1097                 void previsit( const ast::OffsetofExpr * ) {}
    1098                 void previsit( const ast::OffsetPackExpr * ) {}
    1099                 void previsit( const ast::CommaExpr * ) {}
    1100                 void previsit( const ast::LogicalExpr * ) {}
    1101                 void previsit( const ast::ConditionalExpr * ) {}
    1102                 void previsit( const ast::CastExpr * ) {}
    1103                 void previsit( const ast::ConstantExpr * ) {}
    1104 
    1105                 void previsit( const ast::VariableExpr * varExpr ) {
    1106                         visit_children = false;
    1107 
    1108                         if ( auto inst = varExpr->result.as<ast::EnumInstType>() ) {
    1109                                 long long int value;
    1110                                 if ( inst->base->valueOf( varExpr->var, value ) ) {
    1111                                         // enumerators are const expr
    1112                                         return;
    1113                                 }
    1114                         }
    1115                         result = false;
    1116                 }
    1117 
    1118                 bool result = true;
    1119         };
    1120 
    11211029        bool isConstExpr( Expression * expr ) {
    11221030                if ( expr ) {
     
    11381046        }
    11391047
    1140         bool isConstExpr( const ast::Expr * expr ) {
    1141                 if ( expr ) {
    1142                         ast::Pass<ConstExprChecker_new> checker;
    1143                         expr->accept( checker );
    1144                         return checker.core.result;
    1145                 }
    1146                 return true;
    1147         }
    1148 
    1149         bool isConstExpr( const ast::Init * init ) {
    1150                 if ( init ) {
    1151                         ast::Pass<ConstExprChecker_new> checker;
    1152                         init->accept( checker );
    1153                         return checker.core.result;
    1154                 } // if
    1155                 // for all intents and purposes, no initializer means const expr
    1156                 return true;
    1157         }
    1158 
    11591048        bool isConstructor( const std::string & str ) { return str == "?{}"; }
    11601049        bool isDestructor( const std::string & str ) { return str == "^?{}"; }
  • src/InitTweak/InitTweak.h

    r21255675 r6a8882c  
    5959        /// True if the Initializer contains designations
    6060        bool isDesignated( Initializer * init );
    61         bool isDesignated( const ast::Init * init );
    6261
    6362        /// True if the ObjectDecl's Initializer nesting level is not deeper than the depth of its
    6463        /// type, where the depth of its type is the number of nested ArrayTypes + 1
    6564        bool checkInitDepth( ObjectDecl * objDecl );
    66         bool checkInitDepth( const ast::ObjectDecl * objDecl );
    6765
    6866        /// returns the declaration of the function called by the expr (must be ApplicationExpr or UntypedExpr)
     
    109107        bool isConstExpr( Expression * expr );
    110108        bool isConstExpr( Initializer * init );
    111 
    112         bool isConstExpr( const ast::Expr * expr );
    113         bool isConstExpr( const ast::Init * init );
    114109
    115110        /// Modifies objDecl to have:
  • src/ResolvExpr/ResolveTypeof.cc

    r21255675 r6a8882c  
    2929#include "SynTree/Mutator.h"     // for Mutator
    3030#include "SynTree/Type.h"        // for TypeofType, Type
    31 #include "SymTab/Mangler.h"
    32 #include "InitTweak/InitTweak.h" // for isConstExpr
    3331
    3432namespace SymTab {
     
    165163}
    166164
    167 struct FixArrayDimension {
    168         // should not require a mutable symbol table - prevent pass template instantiation
    169         const ast::SymbolTable & _symtab;
    170         FixArrayDimension(const ast::SymbolTable & symtab): _symtab(symtab) {}
    171 
    172         const ast::ArrayType * previsit (const ast::ArrayType * arrayType) {
    173                 if (!arrayType->dimension) return arrayType;
    174                 auto mutType = mutate(arrayType);
    175                 ast::ptr<ast::Type> sizetype = ast::sizeType ? ast::sizeType : new ast::BasicType(ast::BasicType::LongUnsignedInt);
    176                 mutType->dimension = findSingleExpression(arrayType->dimension, sizetype, _symtab);
    177 
    178                 if (InitTweak::isConstExpr(mutType->dimension)) {
    179                         mutType->isVarLen = ast::LengthFlag::FixedLen;
    180                 }
    181                 else {
    182                         mutType->isVarLen = ast::LengthFlag::VariableLen;
    183                 }
    184                 return mutType;
    185         }
    186 };
    187 
    188 const ast::Type * fixArrayType( const ast::Type * type, const ast::SymbolTable & symtab) {
    189         ast::Pass<FixArrayDimension> visitor {symtab};
    190         return type->accept(visitor);
    191 }
    192 
    193 const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ast::SymbolTable & symtab ) {
    194         if (!decl->isTypeFixed) {
    195                 auto mutDecl = mutate(decl);
    196                 auto resolvedType = resolveTypeof(decl->type, symtab);
    197                 resolvedType = fixArrayType(resolvedType, symtab);
    198                 mutDecl->type = resolvedType;
    199 
    200                 // check variable length if object is an array.
    201                 // xxx - should this be part of fixObjectType?
    202 
    203                 /*
    204                 if (auto arrayType = dynamic_cast<const ast::ArrayType *>(resolvedType)) {
    205                         auto dimExpr = findSingleExpression(arrayType->dimension, ast::sizeType, symtab);
    206                         if (auto varexpr = arrayType->dimension.as<ast::VariableExpr>()) {// hoisted previously
    207                                 if (InitTweak::isConstExpr(varexpr->var.strict_as<ast::ObjectDecl>()->init)) {
    208                                         auto mutType = mutate(arrayType);
    209                                         mutType->isVarLen = ast::LengthFlag::VariableLen;
    210                                         mutDecl->type = mutType;
    211                                 }
    212                         }
    213                 }
    214                 */
    215 
    216 
    217                 if (!mutDecl->name.empty())
    218                         mutDecl->mangleName = Mangle::mangle(mutDecl); // do not mangle unnamed variables
    219                
    220                 mutDecl->isTypeFixed = true;
    221                 return mutDecl;
    222         }
    223         return decl;
    224 }
    225 
    226165} // namespace ResolvExpr
    227166
  • src/ResolvExpr/ResolveTypeof.h

    r21255675 r6a8882c  
    2323        class Type;
    2424        class SymbolTable;
    25         class ObjectDecl;
    2625}
    2726
     
    2928        Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
    3029        const ast::Type * resolveTypeof( const ast::Type *, const ast::SymbolTable & );
    31         const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ast::SymbolTable & symtab );
    3230} // namespace ResolvExpr
    3331
  • src/ResolvExpr/Resolver.cc

    r21255675 r6a8882c  
    2626#include "RenameVars.h"                  // for RenameVars, global_renamer
    2727#include "Resolver.h"
    28 #include "ResolveTypeof.h"
    2928#include "ResolvMode.h"                  // for ResolvMode
    3029#include "typeops.h"                     // for extractResultType
    3130#include "Unify.h"                       // for unify
    32 #include "CompilationState.h"
    3331#include "AST/Chain.hpp"
    3432#include "AST/Decl.hpp"
     
    4745#include "SymTab/Autogen.h"              // for SizeType
    4846#include "SymTab/Indexer.h"              // for Indexer
    49 #include "SymTab/Mangler.h"              // for Mangler
    5047#include "SynTree/Declaration.h"         // for ObjectDecl, TypeDecl, Declar...
    5148#include "SynTree/Expression.h"          // for Expression, CastExpr, InitExpr
     
    11821179        } // anonymous namespace
    11831180
    1184         ast::ptr< ast::Expr > findSingleExpression(
    1185                 const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab
    1186         ) {
    1187                 assert( untyped && type );
    1188                 ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type };
    1189                 ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab );
    1190                 removeExtraneousCast( newExpr, symtab );
    1191                 return newExpr;
    1192         }
     1181                ast::ptr< ast::Expr > findSingleExpression(
     1182                        const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab
     1183                ) {
     1184                        assert( untyped && type );
     1185                        ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type };
     1186                        ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab );
     1187                        removeExtraneousCast( newExpr, symtab );
     1188                        return newExpr;
     1189                }
    11931190
    11941191        namespace {
    1195                 bool structOrUnion( const Candidate & i ) {
    1196                         const ast::Type * t = i.expr->result->stripReferences();
    1197                         return dynamic_cast< const ast::StructInstType * >( t ) || dynamic_cast< const ast::UnionInstType * >( t );
    1198                 }
    11991192                /// Predicate for "Candidate has integral type"
    12001193                bool hasIntegralType( const Candidate & i ) {
     
    12441237                ast::ptr< ast::Type > functionReturn = nullptr;
    12451238                ast::CurrentObject currentObject;
    1246                 // for work previously in GenInit
    1247                 static InitTweak::ManagedTypes_new managedTypes;
    1248 
    12491239                bool inEnumDecl = false;
    12501240
     
    12541244                Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; }
    12551245
    1256                 const ast::FunctionDecl * previsit( const ast::FunctionDecl * );
     1246                void previsit( const ast::FunctionDecl * );
    12571247                const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );
    1258                 const ast::ObjectDecl * previsit( const ast::ObjectDecl * );
    1259                 void previsit( const ast::AggregateDecl * );
    1260                 void previsit( const ast::StructDecl * );
     1248                void previsit( const ast::ObjectDecl * );
    12611249                void previsit( const ast::EnumDecl * );
    12621250                const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * );
     
    12791267                const ast::CatchStmt *       postvisit( const ast::CatchStmt * );
    12801268                const ast::WaitForStmt *     previsit( const ast::WaitForStmt * );
    1281                 const ast::WithStmt *        previsit( const ast::WithStmt * );
    12821269
    12831270                const ast::SingleInit *      previsit( const ast::SingleInit * );
    12841271                const ast::ListInit *        previsit( const ast::ListInit * );
    12851272                const ast::ConstructorInit * previsit( const ast::ConstructorInit * );
    1286 
    1287                 void resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd);
    1288 
    1289                 void beginScope() { managedTypes.beginScope(); }
    1290                 void endScope() { managedTypes.endScope(); }
    1291                 bool on_error(ast::ptr<ast::Decl> & decl);
    12921273        };
    12931274        // size_t Resolver_new::traceId = Stats::Heap::new_stacktrace_id("Resolver");
    1294 
    1295         InitTweak::ManagedTypes_new Resolver_new::managedTypes;
    12961275
    12971276        void resolve( ast::TranslationUnit& translationUnit ) {
     
    13181297        }
    13191298
    1320         namespace {
    1321                 const ast::Attribute * handleAttribute(const CodeLocation & loc, const ast::Attribute * attr, const ast::SymbolTable & symtab) {
    1322                         std::string name = attr->normalizedName();
    1323                         if (name == "constructor" || name == "destructor") {
    1324                                 if (attr->params.size() == 1) {
    1325                                         auto arg = attr->params.front();
    1326                                         auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::BasicType::LongLongSignedInt ), symtab );
    1327                                         auto result = eval(arg);
    1328 
    1329                                         auto mutAttr = mutate(attr);
    1330                                         mutAttr->params.front() = resolved;
    1331                                         if (! result.second) {
    1332                                                 SemanticWarning(loc, Warning::GccAttributes,
    1333                                                         toCString( name, " priorities must be integers from 0 to 65535 inclusive: ", arg ) );
    1334                                         }
    1335                                         else {
    1336                                                 auto priority = result.first;
    1337                                                 if (priority < 101) {
    1338                                                         SemanticWarning(loc, Warning::GccAttributes,
    1339                                                                 toCString( name, " priorities from 0 to 100 are reserved for the implementation" ) );
    1340                                                 } else if (priority < 201 && ! buildingLibrary()) {
    1341                                                         SemanticWarning(loc, Warning::GccAttributes,
    1342                                                                 toCString( name, " priorities from 101 to 200 are reserved for the implementation" ) );
    1343                                                 }
    1344                                         }
    1345                                         return mutAttr;
    1346                                 } else if (attr->params.size() > 1) {
    1347                                         SemanticWarning(loc, Warning::GccAttributes, toCString( "too many arguments to ", name, " attribute" ) );
    1348                                 } else {
    1349                                         SemanticWarning(loc, Warning::GccAttributes, toCString( "too few arguments to ", name, " attribute" ) );
    1350                                 }
    1351                         }
    1352                         return attr;
    1353                 }
    1354         }
    1355 
    1356         const ast::FunctionDecl * Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
     1299        void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
    13571300                GuardValue( functionReturn );
    1358 
    1359                 assert (functionDecl->unique());
    1360                 if (!functionDecl->has_body() && !functionDecl->withExprs.empty()) {
    1361                         SemanticError(functionDecl->location, functionDecl, "Function without body has with declarations");
    1362                 }
    1363 
    1364                 if (!functionDecl->isTypeFixed) {
    1365                         auto mutDecl = mutate(functionDecl);
    1366                         auto mutType = mutDecl->type.get_and_mutate();
    1367 
    1368                         for (auto & attr: mutDecl->attributes) {
    1369                                 attr = handleAttribute(mutDecl->location, attr, symtab);
    1370                         }
    1371 
    1372                         // handle assertions. (seems deep)
    1373 
    1374                         symtab.enterScope();
    1375                         for (auto & typeParam : mutType->forall) {
    1376                                 auto mutParam = typeParam.get_and_mutate();
    1377                                 symtab.addType(mutParam);
    1378                                 for (auto & asst : mutParam->assertions) {
    1379                                         asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), symtab);
    1380                                         symtab.addId(asst);
    1381                                 }
    1382                                 typeParam = mutParam;
    1383                         }
    1384 
    1385                         // temporarily adds params to symbol table.
    1386                         // actual scoping rules for params and withexprs differ - see Pass::visit(FunctionDecl)
    1387 
    1388                         std::vector<ast::ptr<ast::Type>> paramTypes;
    1389                         std::vector<ast::ptr<ast::Type>> returnTypes;
    1390 
    1391                         for (auto & param : mutDecl->params) {
    1392                                 param = fixObjectType(param.strict_as<ast::ObjectDecl>(), symtab);
    1393                                 symtab.addId(param);
    1394                                 paramTypes.emplace_back(param->get_type());
    1395                         }
    1396                         for (auto & ret : mutDecl->returns) {
    1397                                 ret = fixObjectType(ret.strict_as<ast::ObjectDecl>(), symtab);
    1398                                 returnTypes.emplace_back(ret->get_type());
    1399                         }
    1400                         // since function type in decl is just a view of param types, need to update that as well
    1401                         mutType->params = std::move(paramTypes);
    1402                         mutType->returns = std::move(returnTypes);
    1403 
    1404                         std::list<ast::ptr<ast::Stmt>> newStmts;
    1405                         resolveWithExprs (mutDecl->withExprs, newStmts);
    1406 
    1407                         if (mutDecl->stmts) {
    1408                                 auto mutStmt = mutDecl->stmts.get_and_mutate();
    1409                                 mutStmt->kids.splice(mutStmt->kids.begin(), std::move(newStmts));
    1410                                 mutDecl->stmts = mutStmt;
    1411                         }
    1412 
    1413                         symtab.leaveScope();
    1414 
    1415                         mutDecl->mangleName = Mangle::mangle(mutDecl);
    1416                         mutDecl->isTypeFixed = true;
    1417                         functionDecl = mutDecl;
    1418                 }
    1419                 managedTypes.handleDWT(functionDecl);
    1420 
    14211301                functionReturn = extractResultType( functionDecl->type );
    1422                 return functionDecl;
    14231302        }
    14241303
     
    14511330        }
    14521331
    1453         const ast::ObjectDecl * Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
     1332        void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
    14541333                // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()],
    14551334                // class-variable `initContext` is changed multiple times because the LHS is analyzed
     
    14591338                // selecting the RHS.
    14601339                GuardValue( currentObject );
    1461 
     1340                currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
    14621341                if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
    14631342                        // enumerator initializers should not use the enum type to initialize, since the
    14641343                        // enum type is still incomplete at this point. Use `int` instead.
    1465                         objectDecl = fixObjectType(objectDecl, symtab);
    14661344                        currentObject = ast::CurrentObject{
    14671345                                objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
    14681346                }
    1469                 else {
    1470                         if (!objectDecl->isTypeFixed) {
    1471                                 auto newDecl = fixObjectType(objectDecl, symtab);
    1472                                 auto mutDecl = mutate(newDecl);
    1473                                
    1474                                 // generate CtorInit wrapper when necessary.
    1475                                 // in certain cases, fixObjectType is called before reaching
    1476                                 // this object in visitor pass, thus disabling CtorInit codegen.
    1477                                 // this happens on aggregate members and function parameters.
    1478                                 if ( InitTweak::tryConstruct( mutDecl ) && ( managedTypes.isManaged( mutDecl ) || ((! isInFunction() || mutDecl->storage.is_static ) && ! InitTweak::isConstExpr( mutDecl->init ) ) ) ) {
    1479                                         // constructed objects cannot be designated
    1480                                         if ( InitTweak::isDesignated( mutDecl->init ) ) SemanticError( mutDecl, "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n" );
    1481                                         // constructed objects should not have initializers nested too deeply
    1482                                         if ( ! InitTweak::checkInitDepth( mutDecl ) ) SemanticError( mutDecl, "Managed object's initializer is too deep " );
    1483 
    1484                                         mutDecl->init = InitTweak::genCtorInit( mutDecl->location, mutDecl );
    1485                                 }
    1486 
    1487                                 objectDecl = mutDecl;
    1488                         }
    1489                         currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
    1490                 }
    1491                
    1492                 return objectDecl;
    1493         }
    1494 
    1495         void Resolver_new::previsit( const ast::AggregateDecl * _aggDecl ) {
    1496                 auto aggDecl = mutate(_aggDecl);
    1497                 assertf(aggDecl == _aggDecl, "type declarations must be unique");
    1498 
    1499                 for (auto & member: aggDecl->members) {
    1500                         // nested type decls are hoisted already. no need to do anything
    1501                         if (auto obj = member.as<ast::ObjectDecl>()) {
    1502                                 member = fixObjectType(obj, symtab);
    1503                         }
    1504                 }
    1505         }
    1506 
    1507         void Resolver_new::previsit( const ast::StructDecl * structDecl ) {
    1508                 previsit(static_cast<const ast::AggregateDecl *>(structDecl));
    1509                 managedTypes.handleStruct(structDecl);
    15101347        }
    15111348
     
    15141351                GuardValue( inEnumDecl );
    15151352                inEnumDecl = true;
    1516                 // don't need to fix types for enum fields
    1517         }
    1518 
     1353        }
    15191354
    15201355        const ast::StaticAssertDecl * Resolver_new::previsit(
     
    19451780        }
    19461781
    1947         const ast::WithStmt * Resolver_new::previsit( const ast::WithStmt * withStmt ) {
    1948                 auto mutStmt = mutate(withStmt);
    1949                 resolveWithExprs(mutStmt->exprs, stmtsToAddBefore);
    1950                 return mutStmt;
    1951         }
    1952 
    1953         void Resolver_new::resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd) {
    1954                 for (auto & expr : exprs) {
    1955                         // only struct- and union-typed expressions are viable candidates
    1956                         expr = findKindExpression( expr, symtab, structOrUnion, "with expression" );
    1957 
    1958                         // if with expression might be impure, create a temporary so that it is evaluated once
    1959                         if ( Tuples::maybeImpure( expr ) ) {
    1960                                 static UniqueName tmpNamer( "_with_tmp_" );
    1961                                 const CodeLocation loc = expr->location;
    1962                                 auto tmp = new ast::ObjectDecl(loc, tmpNamer.newName(), expr->result, new ast::SingleInit(loc, expr ) );
    1963                                 expr = new ast::VariableExpr( loc, tmp );
    1964                                 stmtsToAdd.push_back( new ast::DeclStmt(loc, tmp ) );
    1965                                 if ( InitTweak::isConstructable( tmp->type ) ) {
    1966                                         // generate ctor/dtor and resolve them
    1967                                         tmp->init = InitTweak::genCtorInit( loc, tmp );
    1968                                 }
    1969                                 // since tmp is freshly created, this should modify tmp in-place
    1970                                 tmp->accept( *visitor );
    1971                         }
    1972                 }
    1973         }
    19741782
    19751783
     
    20671875        }
    20681876
    2069         // suppress error on autogen functions and mark invalid autogen as deleted.
    2070         bool Resolver_new::on_error(ast::ptr<ast::Decl> & decl) {
    2071                 if (auto functionDecl = decl.as<ast::FunctionDecl>()) {
    2072                         // xxx - can intrinsic gen ever fail?
    2073                         if (functionDecl->linkage == ast::Linkage::AutoGen) {
    2074                                 auto mutDecl = mutate(functionDecl);
    2075                                 mutDecl->isDeleted = true;
    2076                                 mutDecl->stmts = nullptr;
    2077                                 decl = mutDecl;
    2078                                 return false;
    2079                         }
    2080                 }
    2081                 return true;
    2082         }
    2083 
    20841877} // namespace ResolvExpr
    20851878
  • src/ResolvExpr/SatisfyAssertions.cpp

    r21255675 r6a8882c  
    247247                                auto it = inferred.find( slot );
    248248                                if ( it == inferred.end() ) {
    249                                         // std::cerr << "missing assertion " << slot << std::endl;
     249                                        std::cerr << "missing assertion " << slot << std::endl;
    250250                                        missingSlots.push_back(slot);
    251251                                        continue;
  • src/SymTab/Autogen.cc

    r21255675 r6a8882c  
    3838#include "SynTree/Type.h"          // for FunctionType, Type, TypeInstType
    3939#include "SynTree/Visitor.h"       // for maybeAccept, Visitor, acceptAll
    40 #include "CompilationState.h"
    4140
    4241class Attribute;
     
    347346        void FuncGenerator::resolve( FunctionDecl * dcl ) {
    348347                try {
    349                         if (!useNewAST) // attempt to delay resolver call
    350                                 ResolvExpr::resolveDecl( dcl, indexer );
     348                        ResolvExpr::resolveDecl( dcl, indexer );
    351349                        if ( functionNesting == 0 ) {
    352350                                // forward declare if top-level struct, so that
  • src/SymTab/Autogen.h

    r21255675 r6a8882c  
    167167                fExpr->args.emplace_back( dstParam );
    168168
    169                 ast::ptr<ast::Stmt> listInit = srcParam.buildListInit( fExpr );
     169                const ast::Stmt * listInit = srcParam.buildListInit( fExpr );
    170170
    171171                // fetch next set of arguments
  • src/SymTab/Validate.cc

    r21255675 r6a8882c  
    6464#include "Common/UniqueName.h"         // for UniqueName
    6565#include "Common/utility.h"            // for operator+, cloneAll, deleteAll
    66 #include "CompilationState.h"          // skip some passes in new-ast build
    6766#include "Concurrency/Keywords.h"      // for applyKeywords
    6867#include "FixFunction.h"               // for FixFunction
     
    369368                                mutateAll( translationUnit, compoundliteral );
    370369                        });
    371                         if (!useNewAST) {
    372                                 Stats::Time::TimeBlock("Resolve With Expressions", [&]() {
    373                                         ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables
    374                                 });
    375                         }
     370                        Stats::Time::TimeBlock("Resolve With Expressions", [&]() {
     371                                ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables
     372                        });
    376373                }
    377374                {
    378375                        Stats::Heap::newPass("validate-F");
    379376                        Stats::Time::BlockGuard guard("validate-F");
    380                         if (!useNewAST) {
    381                                 Stats::Time::TimeCall("Fix Object Type",
    382                                         FixObjectType::fix, translationUnit);
    383                         }
     377                        Stats::Time::TimeCall("Fix Object Type",
     378                                FixObjectType::fix, translationUnit);
    384379                        Stats::Time::TimeCall("Array Length",
    385380                                ArrayLength::computeLength, translationUnit);
     
    388383                        Stats::Time::TimeCall("Fix Label Address",
    389384                                mutateAll<LabelAddressFixer>, translationUnit, labelAddrFixer);
    390                         if (!useNewAST) {
    391                                 Stats::Time::TimeCall("Handle Attributes",
    392                                         Validate::handleAttributes, translationUnit);
    393                         }
     385                        Stats::Time::TimeCall("Handle Attributes",
     386                                Validate::handleAttributes, translationUnit);
    394387                }
    395388        }
     
    13471340
    13481341        void ArrayLength::previsit( ArrayType * type ) {
    1349                 if (!useNewAST) {
    1350                         if ( type->dimension ) {
    1351                                 // need to resolve array dimensions early so that constructor code can correctly determine
    1352                                 // if a type is a VLA (and hence whether its elements need to be constructed)
    1353                                 ResolvExpr::findSingleExpression( type->dimension, Validate::SizeType->clone(), indexer );
    1354 
    1355                                 // must re-evaluate whether a type is a VLA, now that more information is available
    1356                                 // (e.g. the dimension may have been an enumerator, which was unknown prior to this step)
    1357                                 type->isVarLen = ! InitTweak::isConstExpr( type->dimension );
    1358                         }
     1342                if ( type->dimension ) {
     1343                        // need to resolve array dimensions early so that constructor code can correctly determine
     1344                        // if a type is a VLA (and hence whether its elements need to be constructed)
     1345                        ResolvExpr::findSingleExpression( type->dimension, Validate::SizeType->clone(), indexer );
     1346
     1347                        // must re-evaluate whether a type is a VLA, now that more information is available
     1348                        // (e.g. the dimension may have been an enumerator, which was unknown prior to this step)
     1349                        type->isVarLen = ! InitTweak::isConstExpr( type->dimension );
    13591350                }
    13601351        }
  • tests/alloc.cfa

    r21255675 r6a8882c  
    208208
    209209
    210         int const_count, dest_count;
    211210        struct Struct { int x; double y; };
    212         void  ?{}( Struct & a ) {                                       // construct
    213                 a.[ x, y ] = [ -1, -1.0 ];
    214         }
    215         void  ?{}( Struct & a, int x, double y ) {      // initialize
    216                 a.[ x, y ] = [ x, y ];
    217                 const_count++;
    218         }
    219         void ^?{}( Struct & a ) {  dest_count++; }      // destruct
    220211        Struct st, st1, sta[dim], sta1[dim], * stp, * stp1;
    221212
     
    338329        printf( "\n" );
    339330
    340         const_count = dest_count = 0;
    341331        stp = new( 42, 42.5 );
    342         assert( const_count == 1 && dest_count == 0 );                                          // assertion for testing
    343332        stp1 = new( 42, 42.5 );
    344         assert( const_count == 2 && dest_count == 0 );                                          // assertion for testing
    345 
    346333        printf( "CFA new initialize\n%d %g %d %g\n", stp->x, stp->y, stp1->x, stp1->y );
    347334        delete( stp, stp1 );
    348         assert( const_count == 2 && dest_count == 2 );                                          // assertion for testing
    349335
    350336        // new, array types
    351337        stp = anew( dim, 42, 42.5 );
    352         assert( const_count == 2 + dim && dest_count == 2 );                            // assertion for testing
    353338        printf( "CFA array new initialize\n" );
    354339        for ( i; dim ) { printf( "%d %g, ", stp[i].x, stp[i].y ); }
    355340        printf( "\n" );
    356 
    357341        stp1 = anew( dim, 42, 42.5 );
    358         assert( const_count == 2 + 2 * dim && dest_count == 2 );                        // assertion for testing
    359342        for ( i; dim ) { printf( "%d %g, ", stp1[i].x, stp1[i].y ); }
    360343        printf( "\n" );
    361344        adelete( stp, stp1 );
    362         assert( const_count == 2 + 2 * dim && dest_count == 2 + 2 * dim);       // assertion for testing
    363345
    364346        // extras
     
    372354        *ip = 0xdeadbeef;
    373355        printf( "CFA deep malloc %#x\n", *ip );
    374 
    375         dp = alloc(5.0`fill); // just for testing multiple free
    376         assert(*dp == 5.0);
    377         free( ip, dp );
     356        free( ip );
    378357
    379358#ifdef ERR1
  • tests/malloc.cfa

    r21255675 r6a8882c  
    319319        free(ip);
    320320
    321         free( (void*) 0p ); // sanity check
     321        free( 0p ); // sanity check
    322322        free( NULL ); // sanity check
    323323
  • tests/manipulatorsOutput3.cfa

    r21255675 r6a8882c  
    156156        sout | nl;
    157157
     158        ui128 = 0x7fffffffffffffff;
     159        ui128 <<= 64;
     160        ui128 += 0xffffffffffffffff;
    158161        sout | left( wd( 160, i128 ) );
    159162        sout | left( sign( wd( 0, i128 ) ) );
     
    174177        sout | left( wd( 160, bin( i128 ) ) );
    175178        sout | left( sign( wd( 160, i128 ) ) );
    176         sout | left( wd( 160, upcase( hex( i128 ) ) ) );
    177         sout | left( wd( 160, upcase( oct( i128 ) ) ) );
    178         sout | left( wd( 160, upcase( bin( i128 ) ) ) );
     179        sout | left( wd( 160, upcase(hex( i128 )) ) );
     180        sout | left( wd( 160, upcase(oct( i128 ) )) );
     181        sout | left( wd( 160, upcase(bin( i128 )) ) );
    179182
    180183        x = 1234;
     
    313316        }
    314317
     318
    315319        // int128 constants (and printing)
    316320        int128 v = 0xffff_ffffffff_ffffffff_L128 + 0xffffffff_ffffffff_ffffffff_ffffffff_L128;
Note: See TracChangeset for help on using the changeset viewer.