Changes in / [21255675:6a8882c]
- Files:
-
- 1 deleted
- 26 edited
-
doc/theses/andrew_beach_MMath/features.tex (deleted)
-
libcfa/src/concurrency/kernel/fwd.hfa (modified) (1 diff)
-
libcfa/src/concurrency/preemption.cfa (modified) (8 diffs)
-
libcfa/src/stdlib.hfa (modified) (2 diffs)
-
src/AST/Convert.cpp (modified) (2 diffs)
-
src/AST/Decl.hpp (modified) (1 diff)
-
src/AST/Init.hpp (modified) (4 diffs)
-
src/AST/Pass.impl.hpp (modified) (2 diffs)
-
src/AST/Pass.proto.hpp (modified) (1 diff)
-
src/AST/Type.cpp (modified) (1 diff)
-
src/CodeGen/CodeGenerator.cc (modified) (1 diff)
-
src/CodeGen/FixMain.cc (modified) (2 diffs)
-
src/CodeGen/FixNames.cc (modified) (2 diffs)
-
src/InitTweak/GenInit.cc (modified) (6 diffs)
-
src/InitTweak/GenInit.h (modified) (1 diff)
-
src/InitTweak/InitTweak.cc (modified) (5 diffs)
-
src/InitTweak/InitTweak.h (modified) (2 diffs)
-
src/ResolvExpr/ResolveTypeof.cc (modified) (2 diffs)
-
src/ResolvExpr/ResolveTypeof.h (modified) (2 diffs)
-
src/ResolvExpr/Resolver.cc (modified) (12 diffs)
-
src/ResolvExpr/SatisfyAssertions.cpp (modified) (1 diff)
-
src/SymTab/Autogen.cc (modified) (2 diffs)
-
src/SymTab/Autogen.h (modified) (1 diff)
-
src/SymTab/Validate.cc (modified) (4 diffs)
-
tests/alloc.cfa (modified) (3 diffs)
-
tests/malloc.cfa (modified) (1 diff)
-
tests/manipulatorsOutput3.cfa (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel/fwd.hfa
r21255675 r6a8882c 65 65 66 66 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 ); 68 71 69 72 static inline uint64_t __tls_rand() { -
libcfa/src/concurrency/preemption.cfa
r21255675 r6a8882c 231 231 } 232 232 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 243 233 //---------- 244 234 // Get data from the TLS block 245 // struct asm_region __cfaasm_get;246 235 uintptr_t __cfatls_get( unsigned long int offset ) __attribute__((__noinline__)); //no inline to avoid problems 247 236 uintptr_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; });250 237 // create a assembler label before 251 238 // marked as clobber all to avoid movement … … 266 253 // create a assembler label before 267 254 // marked as clobber all to avoid movement 268 asm volatile("__cfaasm_d sable_before:":::"memory");255 asm volatile("__cfaasm_disable_before:":::"memory"); 269 256 270 257 with( __cfaabi_tls.preemption_state ) { … … 288 275 // create a assembler label after 289 276 // marked as clobber all to avoid movement 290 asm volatile("__cfaasm_d sable_after:":::"memory");277 asm volatile("__cfaasm_disable_after:":::"memory"); 291 278 } 292 279 … … 296 283 // create a assembler label before 297 284 // marked as clobber all to avoid movement 298 asm volatile("__cfaasm_en ble_before:":::"memory");285 asm volatile("__cfaasm_enable_before:":::"memory"); 299 286 300 287 processor * proc = __cfaabi_tls.this_processor; // Cache the processor now since interrupts can start happening after the atomic store … … 331 318 // create a assembler label after 332 319 // marked as clobber all to avoid movement 333 asm volatile("__cfaasm_en ble_after:":::"memory");320 asm volatile("__cfaasm_enable_after:":::"memory"); 334 321 } 335 322 … … 399 386 } 400 387 401 //-----------------------------------------------------------------------------402 // Some assembly required403 #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 #else414 #define RELOC_PREFIX "$"415 #define RELOC_SUFFIX ""416 #endif417 #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 #else433 #define RELOC_PREFIX "$"434 #define RELOC_SUFFIX ""435 #endif436 #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 #else450 #define RELOC_TAG ""451 #endif452 #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 #else463 #error unknown hardware architecture464 #endif465 466 388 // KERNEL ONLY 467 389 // Check if a __cfactx_switch signal handler shoud defer 468 390 // If true : preemption is safe 469 391 // 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 392 static inline bool preemption_ready() { 478 393 // 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 489 396 // Adjust the pending flag accordingly 490 397 __cfaabi_tls.this_processor->pending_preemption = !ready; … … 561 468 // Kernel Signal Handlers 562 469 //============================================================================================= 470 struct 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 563 510 __cfaabi_dbg_debug_do( static thread_local void * last_interrupt = 0; ) 564 511 … … 583 530 584 531 // 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; 586 540 587 541 __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 101 101 return (T *)pvalloc( sizeof(T) ); // C pvalloc 102 102 } // pvalloc 103 104 void free( T * addr ) {105 free( (void *) addr ); // C free106 } // free107 } // distribution108 109 static inline forall( ttype TT | { void free( TT ); } ) {110 // T* does not take void* and vice-versa111 112 void free( void * addr, TT rest ) {113 free( addr );114 free( rest );115 } // free116 117 forall( dtype T | sized(T) )118 void free( T * addr, TT rest ) {119 free( addr );120 free( rest );121 } // free122 103 } // distribution 123 104 … … 129 110 forall( dtype T | sized(T) ) { 130 111 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]; }; 132 113 struct S_realloc { inline T *; }; 133 114 } -
src/AST/Convert.cpp
r21255675 r6a8882c 2764 2764 old->location, 2765 2765 GET_ACCEPT_1(value, Expr), 2766 (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast:: NoConstruct2766 (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::DoConstruct 2767 2767 ); 2768 2768 } … … 2773 2773 GET_ACCEPT_V(initializers, Init), 2774 2774 GET_ACCEPT_V(designations, Designation), 2775 (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast:: NoConstruct2775 (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::DoConstruct 2776 2776 ); 2777 2777 } -
src/AST/Decl.hpp
r21255675 r6a8882c 79 79 ptr<Expr> asmName; 80 80 bool isDeleted = false; 81 bool isTypeFixed = false;82 81 83 82 DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage, -
src/AST/Init.hpp
r21255675 r6a8882c 50 50 51 51 /// Flag for whether to construct from initialzier 52 enum ConstructFlag { NoConstruct, MaybeConstruct };52 enum ConstructFlag { DoConstruct, MaybeConstruct }; 53 53 54 54 /// Object initializer base class … … 71 71 ptr<Expr> value; 72 72 73 SingleInit( const CodeLocation & loc, const Expr * val, ConstructFlag mc = NoConstruct )73 SingleInit( const CodeLocation & loc, const Expr * val, ConstructFlag mc = DoConstruct ) 74 74 : Init( loc, mc ), value( val ) {} 75 75 … … 90 90 91 91 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 ); 93 93 94 94 using iterator = std::vector<ptr<Init>>::iterator; … … 118 118 ConstructorInit( 119 119 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 ) {} 121 121 122 122 const Init * accept( Visitor & v ) const override { return v.visit( this ); } -
src/AST/Pass.impl.hpp
r21255675 r6a8882c 423 423 } 424 424 catch( SemanticErrorException &e ) { 425 if (__pass::on_error (visitor.core, *i, 0)) 426 errors.append( e ); 425 errors.append( e ); 427 426 } 428 427 … … 684 683 // Do not enter (or leave) a new scope if atFunctionTop. Remember to save the result. 685 684 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); 690 686 }, [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); 695 688 }); 696 689 ValueGuard< bool > guard2( atFunctionTop ); -
src/AST/Pass.proto.hpp
r21255675 r6a8882c 266 266 static void endTrace(core_t &, long) {} 267 267 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 279 268 // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement. 280 269 // All passes which have such functions are assumed desire this behaviour -
src/AST/Type.cpp
r21255675 r6a8882c 211 211 for ( const Type * ty : types ) { 212 212 members.emplace_back( new ObjectDecl{ 213 CodeLocation{}, "", ty, new ListInit( CodeLocation{}, {}, {}, NoConstruct ),213 CodeLocation{}, "", ty, new ListInit( CodeLocation{}, {}, {}, MaybeConstruct ), 214 214 Storage::Classes{}, Linkage::Cforall } ); 215 215 } -
src/CodeGen/CodeGenerator.cc
r21255675 r6a8882c 120 120 // GCC builtins should always be printed unmangled 121 121 if ( options.pretty || decl->linkage.is_gcc_builtin ) return decl->name; 122 if ( LinkageSpec::isMangled(decl->linkage) &&decl->mangleName != "" ) {122 if ( decl->mangleName != "" ) { 123 123 // need to incorporate scope level in order to differentiate names for destructors 124 124 return decl->get_scopedMangleName(); -
src/CodeGen/FixMain.cc
r21255675 r6a8882c 26 26 #include "SynTree/Declaration.h" // for FunctionDecl, operator<< 27 27 #include "SynTree/Type.h" // for FunctionType 28 #include "SymTab/Mangler.h"29 28 30 29 namespace CodeGen { … … 48 47 if( main_signature ) { 49 48 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());51 49 52 50 os << main_signature->get_scopedMangleName() << "("; -
src/CodeGen/FixNames.cc
r21255675 r6a8882c 31 31 #include "SynTree/Type.h" // for Type, BasicType, Type::Qualifiers 32 32 #include "SynTree/Visitor.h" // for Visitor, acceptAll 33 #include "CompilationState.h"34 33 35 34 namespace CodeGen { … … 103 102 if ( dwt->get_name() != "" ) { 104 103 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 ) ); 108 105 dwt->set_scopeLevel( scopeLevel ); 109 106 } // if -
src/InitTweak/GenInit.cc
r21255675 r6a8882c 26 26 #include "AST/Node.hpp" 27 27 #include "AST/Stmt.hpp" 28 #include "CompilationState.h"29 28 #include "CodeGen/OperatorTable.h" 30 29 #include "Common/PassVisitor.h" // for PassVisitor, WithGuards, WithShort... … … 123 122 124 123 void genInit( std::list< Declaration * > & translationUnit ) { 124 fixReturnStatements( translationUnit ); 125 125 HoistArrayDimension::hoistArrayDimension( translationUnit ); 126 fixReturnStatements( translationUnit ); 127 128 if (!useNewAST) { 129 CtorDtor::generateCtorDtor( translationUnit ); 130 } 126 CtorDtor::generateCtorDtor( translationUnit ); 131 127 } 132 128 … … 196 192 197 193 // 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 ); 203 197 // 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; 208 199 209 200 ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, Validate::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) ); … … 254 245 } 255 246 256 // why is this not just on FunctionDecl?257 247 void ManagedTypes::handleDWT( DeclarationWithType * dwt ) { 258 248 // if this function is a user-defined constructor or destructor, mark down the type as "managed" … … 284 274 void ManagedTypes::beginScope() { managedTypes.beginScope(); } 285 275 void ManagedTypes::endScope() { managedTypes.endScope(); } 286 287 bool ManagedTypes_new::isManaged( const ast::Type * type ) const {288 // references are never constructed289 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 managed292 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 managed297 // ValueGuard< Type::Qualifiers > qualifiers( type->get_qualifiers() );298 auto tmp = shallowCopy(type);299 tmp->qualifiers = {};300 // delete tmp at return301 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 C310 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 managed330 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 that334 // polymorphic constructors make generic types managed types335 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(); }345 276 346 277 ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg ) { … … 439 370 // constructable object 440 371 InitExpander_new srcParam{ objDecl->init }, nullParam{ (const ast::Init *)nullptr }; 441 ast::ptr< ast::Expr > dstParam = new ast::VariableExpr(loc, objDecl);442 372 443 373 ast::ptr< ast::Stmt > ctor = SymTab::genImplicitCall( 444 srcParam, dstParam, loc, "?{}", objDecl );374 srcParam, new ast::VariableExpr{ loc, objDecl }, loc, "?{}", objDecl ); 445 375 ast::ptr< ast::Stmt > dtor = SymTab::genImplicitCall( 446 nullParam, dstParam, loc, "^?{}", objDecl,376 nullParam, new ast::VariableExpr{ loc, objDecl }, loc, "^?{}", objDecl, 447 377 SymTab::LoopBackward ); 448 378 -
src/InitTweak/GenInit.h
r21255675 r6a8882c 52 52 GenPoly::ScopedSet< std::string > managedTypes; 53 53 }; 54 55 class ManagedTypes_new {56 public:57 bool isManaged( const ast::ObjectDecl * objDecl ) const ; // determine if object is managed58 bool isManaged( const ast::Type * type ) const; // determine if type is managed59 60 void handleDWT( const ast::DeclWithType * dwt ); // add type to managed if ctor/dtor61 void handleStruct( const ast::StructDecl * aggregateDecl ); // add type to managed if child is managed62 63 void beginScope();64 void endScope();65 private:66 GenPoly::ScopedSet< std::string > managedTypes;67 };68 54 } // namespace 69 55 -
src/InitTweak/InitTweak.cc
r21255675 r6a8882c 87 87 }; 88 88 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 designations94 if ( result ) visit_children = false;95 }96 97 void previsit( const ast::Designation * des ) {98 // short circuit if we already know there are designations99 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 126 89 struct InitFlattener_old : public WithShortCircuiting { 127 90 void previsit( SingleInit * singleInit ) { … … 159 122 maybeAccept( objDecl->init, checker ); 160 123 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;173 124 } 174 125 … … 407 358 if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) { 408 359 for ( const ast::Init * init : *listInit ) { 409 buildCallExpr( shallowCopy(callExpr), index, dimension, init, out );360 buildCallExpr( callExpr, index, dimension, init, out ); 410 361 } 411 362 } else { 412 buildCallExpr( shallowCopy(callExpr), index, dimension, init, out );363 buildCallExpr( callExpr, index, dimension, init, out ); 413 364 } 414 365 } else { … … 1076 1027 }; 1077 1028 1078 struct ConstExprChecker_new : public ast::WithShortCircuiting {1079 // most expressions are not const expr1080 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 constexpr1087 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 children1094 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 expr1112 return;1113 }1114 }1115 result = false;1116 }1117 1118 bool result = true;1119 };1120 1121 1029 bool isConstExpr( Expression * expr ) { 1122 1030 if ( expr ) { … … 1138 1046 } 1139 1047 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 } // if1155 // for all intents and purposes, no initializer means const expr1156 return true;1157 }1158 1159 1048 bool isConstructor( const std::string & str ) { return str == "?{}"; } 1160 1049 bool isDestructor( const std::string & str ) { return str == "^?{}"; } -
src/InitTweak/InitTweak.h
r21255675 r6a8882c 59 59 /// True if the Initializer contains designations 60 60 bool isDesignated( Initializer * init ); 61 bool isDesignated( const ast::Init * init );62 61 63 62 /// True if the ObjectDecl's Initializer nesting level is not deeper than the depth of its 64 63 /// type, where the depth of its type is the number of nested ArrayTypes + 1 65 64 bool checkInitDepth( ObjectDecl * objDecl ); 66 bool checkInitDepth( const ast::ObjectDecl * objDecl );67 65 68 66 /// returns the declaration of the function called by the expr (must be ApplicationExpr or UntypedExpr) … … 109 107 bool isConstExpr( Expression * expr ); 110 108 bool isConstExpr( Initializer * init ); 111 112 bool isConstExpr( const ast::Expr * expr );113 bool isConstExpr( const ast::Init * init );114 109 115 110 /// Modifies objDecl to have: -
src/ResolvExpr/ResolveTypeof.cc
r21255675 r6a8882c 29 29 #include "SynTree/Mutator.h" // for Mutator 30 30 #include "SynTree/Type.h" // for TypeofType, Type 31 #include "SymTab/Mangler.h"32 #include "InitTweak/InitTweak.h" // for isConstExpr33 31 34 32 namespace SymTab { … … 165 163 } 166 164 167 struct FixArrayDimension {168 // should not require a mutable symbol table - prevent pass template instantiation169 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 previously207 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 variables219 220 mutDecl->isTypeFixed = true;221 return mutDecl;222 }223 return decl;224 }225 226 165 } // namespace ResolvExpr 227 166 -
src/ResolvExpr/ResolveTypeof.h
r21255675 r6a8882c 23 23 class Type; 24 24 class SymbolTable; 25 class ObjectDecl;26 25 } 27 26 … … 29 28 Type *resolveTypeof( Type*, const SymTab::Indexer &indexer ); 30 29 const ast::Type * resolveTypeof( const ast::Type *, const ast::SymbolTable & ); 31 const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ast::SymbolTable & symtab );32 30 } // namespace ResolvExpr 33 31 -
src/ResolvExpr/Resolver.cc
r21255675 r6a8882c 26 26 #include "RenameVars.h" // for RenameVars, global_renamer 27 27 #include "Resolver.h" 28 #include "ResolveTypeof.h"29 28 #include "ResolvMode.h" // for ResolvMode 30 29 #include "typeops.h" // for extractResultType 31 30 #include "Unify.h" // for unify 32 #include "CompilationState.h"33 31 #include "AST/Chain.hpp" 34 32 #include "AST/Decl.hpp" … … 47 45 #include "SymTab/Autogen.h" // for SizeType 48 46 #include "SymTab/Indexer.h" // for Indexer 49 #include "SymTab/Mangler.h" // for Mangler50 47 #include "SynTree/Declaration.h" // for ObjectDecl, TypeDecl, Declar... 51 48 #include "SynTree/Expression.h" // for Expression, CastExpr, InitExpr … … 1182 1179 } // anonymous namespace 1183 1180 1184 ast::ptr< ast::Expr > findSingleExpression(1185 const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab1186 ) {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 } 1193 1190 1194 1191 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 }1199 1192 /// Predicate for "Candidate has integral type" 1200 1193 bool hasIntegralType( const Candidate & i ) { … … 1244 1237 ast::ptr< ast::Type > functionReturn = nullptr; 1245 1238 ast::CurrentObject currentObject; 1246 // for work previously in GenInit1247 static InitTweak::ManagedTypes_new managedTypes;1248 1249 1239 bool inEnumDecl = false; 1250 1240 … … 1254 1244 Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; } 1255 1245 1256 const ast::FunctionDecl *previsit( const ast::FunctionDecl * );1246 void previsit( const ast::FunctionDecl * ); 1257 1247 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 * ); 1261 1249 void previsit( const ast::EnumDecl * ); 1262 1250 const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * ); … … 1279 1267 const ast::CatchStmt * postvisit( const ast::CatchStmt * ); 1280 1268 const ast::WaitForStmt * previsit( const ast::WaitForStmt * ); 1281 const ast::WithStmt * previsit( const ast::WithStmt * );1282 1269 1283 1270 const ast::SingleInit * previsit( const ast::SingleInit * ); 1284 1271 const ast::ListInit * previsit( const ast::ListInit * ); 1285 1272 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);1292 1273 }; 1293 1274 // size_t Resolver_new::traceId = Stats::Heap::new_stacktrace_id("Resolver"); 1294 1295 InitTweak::ManagedTypes_new Resolver_new::managedTypes;1296 1275 1297 1276 void resolve( ast::TranslationUnit& translationUnit ) { … … 1318 1297 } 1319 1298 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 ) { 1357 1300 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 well1401 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 1421 1301 functionReturn = extractResultType( functionDecl->type ); 1422 return functionDecl;1423 1302 } 1424 1303 … … 1451 1330 } 1452 1331 1453 const ast::ObjectDecl *Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {1332 void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) { 1454 1333 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 1455 1334 // class-variable `initContext` is changed multiple times because the LHS is analyzed … … 1459 1338 // selecting the RHS. 1460 1339 GuardValue( currentObject ); 1461 1340 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() }; 1462 1341 if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) { 1463 1342 // enumerator initializers should not use the enum type to initialize, since the 1464 1343 // enum type is still incomplete at this point. Use `int` instead. 1465 objectDecl = fixObjectType(objectDecl, symtab);1466 1344 currentObject = ast::CurrentObject{ 1467 1345 objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } }; 1468 1346 } 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 reaching1476 // 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 designated1480 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 deeply1482 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 anything1501 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);1510 1347 } 1511 1348 … … 1514 1351 GuardValue( inEnumDecl ); 1515 1352 inEnumDecl = true; 1516 // don't need to fix types for enum fields 1517 } 1518 1353 } 1519 1354 1520 1355 const ast::StaticAssertDecl * Resolver_new::previsit( … … 1945 1780 } 1946 1781 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 candidates1956 expr = findKindExpression( expr, symtab, structOrUnion, "with expression" );1957 1958 // if with expression might be impure, create a temporary so that it is evaluated once1959 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 them1967 tmp->init = InitTweak::genCtorInit( loc, tmp );1968 }1969 // since tmp is freshly created, this should modify tmp in-place1970 tmp->accept( *visitor );1971 }1972 }1973 }1974 1782 1975 1783 … … 2067 1875 } 2068 1876 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 2084 1877 } // namespace ResolvExpr 2085 1878 -
src/ResolvExpr/SatisfyAssertions.cpp
r21255675 r6a8882c 247 247 auto it = inferred.find( slot ); 248 248 if ( it == inferred.end() ) { 249 //std::cerr << "missing assertion " << slot << std::endl;249 std::cerr << "missing assertion " << slot << std::endl; 250 250 missingSlots.push_back(slot); 251 251 continue; -
src/SymTab/Autogen.cc
r21255675 r6a8882c 38 38 #include "SynTree/Type.h" // for FunctionType, Type, TypeInstType 39 39 #include "SynTree/Visitor.h" // for maybeAccept, Visitor, acceptAll 40 #include "CompilationState.h"41 40 42 41 class Attribute; … … 347 346 void FuncGenerator::resolve( FunctionDecl * dcl ) { 348 347 try { 349 if (!useNewAST) // attempt to delay resolver call 350 ResolvExpr::resolveDecl( dcl, indexer ); 348 ResolvExpr::resolveDecl( dcl, indexer ); 351 349 if ( functionNesting == 0 ) { 352 350 // forward declare if top-level struct, so that -
src/SymTab/Autogen.h
r21255675 r6a8882c 167 167 fExpr->args.emplace_back( dstParam ); 168 168 169 ast::ptr<ast::Stmt>listInit = srcParam.buildListInit( fExpr );169 const ast::Stmt * listInit = srcParam.buildListInit( fExpr ); 170 170 171 171 // fetch next set of arguments -
src/SymTab/Validate.cc
r21255675 r6a8882c 64 64 #include "Common/UniqueName.h" // for UniqueName 65 65 #include "Common/utility.h" // for operator+, cloneAll, deleteAll 66 #include "CompilationState.h" // skip some passes in new-ast build67 66 #include "Concurrency/Keywords.h" // for applyKeywords 68 67 #include "FixFunction.h" // for FixFunction … … 369 368 mutateAll( translationUnit, compoundliteral ); 370 369 }); 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 }); 376 373 } 377 374 { 378 375 Stats::Heap::newPass("validate-F"); 379 376 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); 384 379 Stats::Time::TimeCall("Array Length", 385 380 ArrayLength::computeLength, translationUnit); … … 388 383 Stats::Time::TimeCall("Fix Label Address", 389 384 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); 394 387 } 395 388 } … … 1347 1340 1348 1341 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 ); 1359 1350 } 1360 1351 } -
tests/alloc.cfa
r21255675 r6a8882c 208 208 209 209 210 int const_count, dest_count;211 210 struct Struct { int x; double y; }; 212 void ?{}( Struct & a ) { // construct213 a.[ x, y ] = [ -1, -1.0 ];214 }215 void ?{}( Struct & a, int x, double y ) { // initialize216 a.[ x, y ] = [ x, y ];217 const_count++;218 }219 void ^?{}( Struct & a ) { dest_count++; } // destruct220 211 Struct st, st1, sta[dim], sta1[dim], * stp, * stp1; 221 212 … … 338 329 printf( "\n" ); 339 330 340 const_count = dest_count = 0;341 331 stp = new( 42, 42.5 ); 342 assert( const_count == 1 && dest_count == 0 ); // assertion for testing343 332 stp1 = new( 42, 42.5 ); 344 assert( const_count == 2 && dest_count == 0 ); // assertion for testing345 346 333 printf( "CFA new initialize\n%d %g %d %g\n", stp->x, stp->y, stp1->x, stp1->y ); 347 334 delete( stp, stp1 ); 348 assert( const_count == 2 && dest_count == 2 ); // assertion for testing349 335 350 336 // new, array types 351 337 stp = anew( dim, 42, 42.5 ); 352 assert( const_count == 2 + dim && dest_count == 2 ); // assertion for testing353 338 printf( "CFA array new initialize\n" ); 354 339 for ( i; dim ) { printf( "%d %g, ", stp[i].x, stp[i].y ); } 355 340 printf( "\n" ); 356 357 341 stp1 = anew( dim, 42, 42.5 ); 358 assert( const_count == 2 + 2 * dim && dest_count == 2 ); // assertion for testing359 342 for ( i; dim ) { printf( "%d %g, ", stp1[i].x, stp1[i].y ); } 360 343 printf( "\n" ); 361 344 adelete( stp, stp1 ); 362 assert( const_count == 2 + 2 * dim && dest_count == 2 + 2 * dim); // assertion for testing363 345 364 346 // extras … … 372 354 *ip = 0xdeadbeef; 373 355 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 ); 378 357 379 358 #ifdef ERR1 -
tests/malloc.cfa
r21255675 r6a8882c 319 319 free(ip); 320 320 321 free( (void*)0p ); // sanity check321 free( 0p ); // sanity check 322 322 free( NULL ); // sanity check 323 323 -
tests/manipulatorsOutput3.cfa
r21255675 r6a8882c 156 156 sout | nl; 157 157 158 ui128 = 0x7fffffffffffffff; 159 ui128 <<= 64; 160 ui128 += 0xffffffffffffffff; 158 161 sout | left( wd( 160, i128 ) ); 159 162 sout | left( sign( wd( 0, i128 ) ) ); … … 174 177 sout | left( wd( 160, bin( i128 ) ) ); 175 178 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 )) ) ); 179 182 180 183 x = 1234; … … 313 316 } 314 317 318 315 319 // int128 constants (and printing) 316 320 int128 v = 0xffff_ffffffff_ffffffff_L128 + 0xffffffff_ffffffff_ffffffff_ffffffff_L128;
Note:
See TracChangeset
for help on using the changeset viewer.