Changes in / [8d61d620:49dee5e]
- Location:
- src
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Stmt.hpp
r8d61d620 r49dee5e 143 143 144 144 IfStmt( const CodeLocation & loc, const Expr * cond, const Stmt * thenPart, 145 const Stmt * elsePart = nullptr, std::vector<ptr<Stmt>> && inits = {},145 Stmt * const elsePart, std::vector<ptr<Stmt>> && inits, 146 146 std::vector<Label> && labels = {} ) 147 147 : Stmt(loc, std::move(labels)), cond(cond), thenPart(thenPart), elsePart(elsePart), -
src/Common/utility.h
r8d61d620 r49dee5e 34 34 class Expression; 35 35 36 /// bring std::move into global scope37 using std::move;38 39 /// partner to move that copies any copyable type40 template<typename T>41 T copy( const T & x ) { return x; }42 43 36 template< typename T > 44 37 static inline T * maybeClone( const T *orig ) { -
src/InitTweak/InitTweak.cc
r8d61d620 r49dee5e 22 22 23 23 #include "AST/Expr.hpp" 24 #include "AST/Init.hpp"25 24 #include "AST/Node.hpp" 26 #include "AST/Pass.hpp"27 25 #include "AST/Stmt.hpp" 28 26 #include "AST/Type.hpp" … … 87 85 }; 88 86 89 struct InitFlattener _old: public WithShortCircuiting {87 struct InitFlattener : public WithShortCircuiting { 90 88 void previsit( SingleInit * singleInit ) { 91 89 visit_children = false; … … 95 93 }; 96 94 97 struct InitFlattener_new : public ast::WithShortCircuiting { 98 std::vector< ast::ptr< ast::Expr > > argList; 99 100 void previsit( const ast::SingleInit * singleInit ) { 101 visit_children = false; 102 argList.emplace_back( singleInit->value ); 103 } 104 }; 105 106 } // anonymous namespace 95 } 107 96 108 97 std::list< Expression * > makeInitList( Initializer * init ) { 109 PassVisitor<InitFlattener _old> flattener;98 PassVisitor<InitFlattener> flattener; 110 99 maybeAccept( init, flattener ); 111 100 return flattener.pass.argList; … … 125 114 126 115 std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ) { 127 ast::Pass< InitFlattener_new > flattener; 128 maybe_accept( init, flattener ); 129 return std::move( flattener.pass.argList ); 116 #warning unimplmented 117 (void)init; 118 assert(false); 119 return {}; 130 120 } 131 121 … … 319 309 virtual std::vector< ast::ptr< ast::Expr > > next( IndexList & indices ) = 0; 320 310 virtual ast::ptr< ast::Stmt > buildListInit( 321 ast::UntypedExpr * callExpr, IndexList & indices ) = 0;311 const ast::UntypedExpr * callExpr, IndexList & indices ) = 0; 322 312 }; 323 313 324 314 namespace { 325 template< typename Out >326 void buildCallExpr(327 ast::UntypedExpr * callExpr, const ast::Expr * index, const ast::Expr * dimension,328 const ast::Init * init, Out & out329 ) {330 const CodeLocation & loc = init->location;331 332 auto cond = new ast::UntypedExpr{333 loc, new ast::NameExpr{ loc, "?<?" }, { index, dimension } };334 335 std::vector< ast::ptr< ast::Expr > > args = makeInitList( init );336 splice( callExpr->args, args );337 338 out.emplace_back( new ast::IfStmt{ loc, cond, new ast::ExprStmt{ loc, callExpr } } );339 340 out.emplace_back( new ast::ExprStmt{341 loc, new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, "++?" }, { index } } } );342 }343 344 template< typename Out >345 void build(346 ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices,347 const ast::Init * init, Out & out348 ) {349 if ( indices.empty() ) return;350 351 unsigned idx = 0;352 353 const ast::Expr * index = indices[idx++];354 assert( idx != indices.size() );355 const ast::Expr * dimension = indices[idx++];356 357 if ( idx == indices.size() ) {358 if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) {359 for ( const ast::Init * init : *listInit ) {360 buildCallExpr( callExpr, index, dimension, init, out );361 }362 } else {363 buildCallExpr( callExpr, index, dimension, init, out );364 }365 } else {366 const CodeLocation & loc = init->location;367 368 unsigned long cond = 0;369 auto listInit = dynamic_cast< const ast::ListInit * >( init );370 if ( ! listInit ) { SemanticError( loc, "unbalanced list initializers" ); }371 372 static UniqueName targetLabel( "L__autogen__" );373 ast::Label switchLabel{374 loc, targetLabel.newName(), { new ast::Attribute{ "unused" } } };375 376 std::vector< ast::ptr< ast::Stmt > > branches;377 for ( const ast::Init * init : *listInit ) {378 auto condition = ast::ConstantExpr::from_ulong( loc, cond );379 ++cond;380 381 std::vector< ast::ptr< ast::Stmt > > stmts;382 build( callExpr, indices, init, stmts );383 stmts.emplace_back(384 new ast::BranchStmt{ loc, ast::BranchStmt::Break, switchLabel } );385 branches.emplace_back( new ast::CaseStmt{ loc, condition, std::move( stmts ) } );386 }387 out.emplace_back( new ast::SwitchStmt{ loc, index, std::move( branches ) } );388 out.emplace_back( new ast::NullStmt{ loc, { switchLabel } } );389 }390 }391 392 315 class InitImpl_new final : public InitExpander_new::ExpanderImpl { 393 316 ast::ptr< ast::Init > init; … … 400 323 401 324 ast::ptr< ast::Stmt > buildListInit( 402 ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices325 const ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices 403 326 ) override { 404 // If array came with an initializer list, initialize each element. We may have more 405 // initializers than elements of the array; need to check at each index that we have 406 // not exceeded size. We may have fewer initializers than elements in the array; need 407 // to default-construct remaining elements. To accomplish this, generate switch 408 // statement consuming all of expander's elements 409 410 if ( ! init ) return {}; 411 412 std::list< ast::ptr< ast::Stmt > > stmts; 413 build( callExpr, indices, init, stmts ); 414 if ( stmts.empty() ) { 415 return {}; 416 } else { 417 auto block = new ast::CompoundStmt{ init->location, std::move( stmts ) }; 418 init = nullptr; // consumed in creating the list init 419 return block; 420 } 327 #warning unimplemented 328 (void)callExpr; (void)indices; 329 assert(false); 330 return {}; 421 331 } 422 332 }; … … 430 340 InitExpander_new::IndexList & indices 431 341 ) override { 432 if ( ! arg ) return {}; 433 434 const CodeLocation & loc = arg->location; 435 const ast::Expr * expr = arg; 436 for ( auto it = indices.rbegin(); it != indices.rend(); ++it ) { 437 // go through indices and layer on subscript exprs ?[?] 438 ++it; 439 expr = new ast::UntypedExpr{ 440 loc, new ast::NameExpr{ loc, "?[?]" }, { expr, *it } }; 441 } 442 return { expr }; 342 #warning unimplemented 343 (void)indices; 344 assert(false); 345 return {}; 443 346 } 444 347 445 348 ast::ptr< ast::Stmt > buildListInit( 446 ast::UntypedExpr *, InitExpander_new::IndexList &349 const ast::UntypedExpr *, InitExpander_new::IndexList & 447 350 ) override { 448 351 return {}; … … 466 369 /// builds statement which has the same semantics as a C-style list initializer (for array 467 370 /// initializers) using callExpr as the base expression to perform initialization 468 ast::ptr< ast::Stmt > InitExpander_new::buildListInit( ast::UntypedExpr * callExpr ) {371 ast::ptr< ast::Stmt > InitExpander_new::buildListInit( const ast::UntypedExpr * callExpr ) { 469 372 return expander->buildListInit( callExpr, indices ); 470 373 } -
src/InitTweak/InitTweak.h
r8d61d620 r49dee5e 154 154 155 155 /// builds statement which has the same semantics as a C-style list initializer (for array 156 /// initializers) using callExpr as the base expression to perform initialization. 157 /// Mutates callExpr 158 ast::ptr< ast::Stmt > buildListInit( ast::UntypedExpr * callExpr ); 156 /// initializers) using callExpr as the base expression to perform initialization 157 ast::ptr< ast::Stmt > buildListInit( const ast::UntypedExpr * callExpr ); 159 158 160 159 void addArrayIndex( const ast::Expr * index, const ast::Expr * dimension ); -
src/ResolvExpr/AlternativeFinder.cc
r8d61d620 r49dee5e 56 56 #define PRINT( text ) if ( resolvep ) { text } 57 57 //#define DEBUG_COST 58 59 using std::move; 60 61 /// copies any copyable type 62 template<typename T> 63 T copy(const T& x) { return x; } 58 64 59 65 namespace ResolvExpr { -
src/ResolvExpr/CandidateFinder.cpp
r8d61d620 r49dee5e 39 39 #include "AST/SymbolTable.hpp" 40 40 #include "AST/Type.hpp" 41 #include "Common/utility.h" // for move, copy42 41 #include "SymTab/Mangler.h" 43 42 #include "SymTab/Validate.h" // for validateType … … 47 46 48 47 namespace ResolvExpr { 48 49 using std::move; 50 51 /// partner to move that copies any copyable type 52 template<typename T> 53 T copy( const T & x ) { return x; } 49 54 50 55 const ast::Expr * referenceToRvalueConversion( const ast::Expr * expr, Cost & cost ) { -
src/SymTab/FixFunction.cc
r8d61d620 r49dee5e 18 18 #include <list> // for list 19 19 20 #include "AST/Decl.hpp" 21 #include "AST/Pass.hpp" 22 #include "AST/Type.hpp" 23 #include "Common/utility.h" // for maybeClone, copy 20 #include "Common/utility.h" // for maybeClone 24 21 #include "SynTree/Declaration.h" // for FunctionDecl, ObjectDecl, Declarati... 25 22 #include "SynTree/Expression.h" // for Expression … … 27 24 28 25 namespace SymTab { 29 class FixFunction_old : public WithShortCircuiting { 30 typedef Mutator Parent; 31 public: 32 FixFunction_old() : isVoid( false ) {} 26 FixFunction::FixFunction() : isVoid( false ) {} 33 27 34 void premutate(FunctionDecl *functionDecl);35 DeclarationWithType* postmutate(FunctionDecl *functionDecl);36 28 37 Type * postmutate(ArrayType * arrayType); 38 39 void premutate(ArrayType * arrayType); 40 void premutate(VoidType * voidType); 41 void premutate(BasicType * basicType); 42 void premutate(PointerType * pointerType); 43 void premutate(StructInstType * aggregateUseType); 44 void premutate(UnionInstType * aggregateUseType); 45 void premutate(EnumInstType * aggregateUseType); 46 void premutate(TraitInstType * aggregateUseType); 47 void premutate(TypeInstType * aggregateUseType); 48 void premutate(TupleType * tupleType); 49 void premutate(VarArgsType * varArgsType); 50 void premutate(ZeroType * zeroType); 51 void premutate(OneType * oneType); 52 53 bool isVoid; 54 }; 55 56 DeclarationWithType * FixFunction_old::postmutate(FunctionDecl *functionDecl) { 29 DeclarationWithType * FixFunction::postmutate(FunctionDecl *functionDecl) { 57 30 // can't delete function type because it may contain assertions, so transfer ownership to new object 58 31 ObjectDecl *pointer = new ObjectDecl( functionDecl->name, functionDecl->get_storageClasses(), functionDecl->linkage, nullptr, new PointerType( Type::Qualifiers(), functionDecl->type ), nullptr, functionDecl->attributes ); … … 68 41 // does not cause an error 69 42 70 Type * FixFunction _old::postmutate(ArrayType *arrayType) {43 Type * FixFunction::postmutate(ArrayType *arrayType) { 71 44 // need to recursively mutate the base type in order for multi-dimensional arrays to work. 72 45 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->isVarLen, arrayType->isStatic ); … … 78 51 } 79 52 80 void FixFunction _old::premutate(VoidType *) {53 void FixFunction::premutate(VoidType *) { 81 54 isVoid = true; 82 55 } 83 56 84 void FixFunction _old::premutate(FunctionDecl *) { visit_children = false; }85 void FixFunction _old::premutate(ArrayType *) { visit_children = false; }86 void FixFunction _old::premutate(BasicType *) { visit_children = false; }87 void FixFunction _old::premutate(PointerType *) { visit_children = false; }88 void FixFunction _old::premutate(StructInstType *) { visit_children = false; }89 void FixFunction _old::premutate(UnionInstType *) { visit_children = false; }90 void FixFunction _old::premutate(EnumInstType *) { visit_children = false; }91 void FixFunction _old::premutate(TraitInstType *) { visit_children = false; }92 void FixFunction _old::premutate(TypeInstType *) { visit_children = false; }93 void FixFunction _old::premutate(TupleType *) { visit_children = false; }94 void FixFunction _old::premutate(VarArgsType *) { visit_children = false; }95 void FixFunction _old::premutate(ZeroType *) { visit_children = false; }96 void FixFunction _old::premutate(OneType *) { visit_children = false; }57 void FixFunction::premutate(FunctionDecl *) { visit_children = false; } 58 void FixFunction::premutate(ArrayType *) { visit_children = false; } 59 void FixFunction::premutate(BasicType *) { visit_children = false; } 60 void FixFunction::premutate(PointerType *) { visit_children = false; } 61 void FixFunction::premutate(StructInstType *) { visit_children = false; } 62 void FixFunction::premutate(UnionInstType *) { visit_children = false; } 63 void FixFunction::premutate(EnumInstType *) { visit_children = false; } 64 void FixFunction::premutate(TraitInstType *) { visit_children = false; } 65 void FixFunction::premutate(TypeInstType *) { visit_children = false; } 66 void FixFunction::premutate(TupleType *) { visit_children = false; } 67 void FixFunction::premutate(VarArgsType *) { visit_children = false; } 68 void FixFunction::premutate(ZeroType *) { visit_children = false; } 69 void FixFunction::premutate(OneType *) { visit_children = false; } 97 70 98 71 bool fixFunction( DeclarationWithType *& dwt ) { 99 PassVisitor<FixFunction _old> fixer;72 PassVisitor<FixFunction> fixer; 100 73 dwt = dwt->acceptMutator( fixer ); 101 74 return fixer.pass.isVoid; 102 75 } 103 104 namespace {105 struct FixFunction_new final : public ast::WithShortCircuiting {106 bool isVoid = false;107 108 void premutate( const ast::FunctionDecl * ) { visit_children = false; }109 110 const ast::DeclWithType * postmutate( const ast::FunctionDecl * func ) {111 return new ast::ObjectDecl{112 func->location, func->name, new ast::PointerType{ func->type }, nullptr,113 func->storage, func->linkage, nullptr, copy( func->attributes ) };114 }115 116 void premutate( const ast::ArrayType * ) { visit_children = false; }117 118 const ast::Type * postmutate( const ast::ArrayType * array ) {119 return new ast::PointerType{120 array->base, array->dimension, array->isVarLen, array->isStatic,121 array->qualifiers };122 }123 124 void premutate( const ast::VoidType * ) { isVoid = true; }125 126 void premutate( const ast::BasicType * ) { visit_children = false; }127 void premutate( const ast::PointerType * ) { visit_children = false; }128 void premutate( const ast::StructInstType * ) { visit_children = false; }129 void premutate( const ast::UnionInstType * ) { visit_children = false; }130 void premutate( const ast::EnumInstType * ) { visit_children = false; }131 void premutate( const ast::TraitInstType * ) { visit_children = false; }132 void premutate( const ast::TypeInstType * ) { visit_children = false; }133 void premutate( const ast::TupleType * ) { visit_children = false; }134 void premutate( const ast::VarArgsType * ) { visit_children = false; }135 void premutate( const ast::ZeroType * ) { visit_children = false; }136 void premutate( const ast::OneType * ) { visit_children = false; }137 };138 } // anonymous namespace139 140 const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid ) {141 ast::Pass< FixFunction_new > fixer;142 dwt = dwt->accept( fixer );143 isVoid |= fixer.pass.isVoid;144 return dwt;145 }146 147 76 } // namespace SymTab 148 77 -
src/SymTab/FixFunction.h
r8d61d620 r49dee5e 19 19 #include "SynTree/SynTree.h" // for Types 20 20 21 namespace ast { 22 class DeclWithType; 23 } 21 namespace SymTab { 22 /// Replaces function and array types by equivalent pointer types. 23 class FixFunction : public WithShortCircuiting { 24 typedef Mutator Parent; 25 public: 26 FixFunction(); 24 27 25 namespace SymTab { 26 /// Replaces function and array types by equivalent pointer types. Returns true if type is 27 /// void 28 void premutate(FunctionDecl *functionDecl); 29 DeclarationWithType* postmutate(FunctionDecl *functionDecl); 30 31 Type * postmutate(ArrayType * arrayType); 32 33 void premutate(ArrayType * arrayType); 34 void premutate(VoidType * voidType); 35 void premutate(BasicType * basicType); 36 void premutate(PointerType * pointerType); 37 void premutate(StructInstType * aggregateUseType); 38 void premutate(UnionInstType * aggregateUseType); 39 void premutate(EnumInstType * aggregateUseType); 40 void premutate(TraitInstType * aggregateUseType); 41 void premutate(TypeInstType * aggregateUseType); 42 void premutate(TupleType * tupleType); 43 void premutate(VarArgsType * varArgsType); 44 void premutate(ZeroType * zeroType); 45 void premutate(OneType * oneType); 46 47 bool isVoid; 48 }; 49 28 50 bool fixFunction( DeclarationWithType *& ); 29 30 /// Returns declaration with function and array types replaced by equivalent pointer types.31 /// Sets isVoid to true if type is void32 const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid );33 51 } // namespace SymTab 34 52 -
src/SymTab/Validate.cc
r8d61d620 r49dee5e 46 46 #include <utility> // for pair 47 47 48 #include "AST/Decl.hpp"49 #include "AST/Node.hpp"50 #include "AST/Pass.hpp"51 #include "AST/SymbolTable.hpp"52 #include "AST/Type.hpp"53 48 #include "CodeGen/CodeGenerator.h" // for genName 54 49 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign … … 129 124 130 125 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 131 struct EnumAndPointerDecay _old{126 struct EnumAndPointerDecay { 132 127 void previsit( EnumDecl *aggregateDecl ); 133 128 void previsit( FunctionType *func ); … … 135 130 136 131 /// Associates forward declarations of aggregates with their definitions 137 struct LinkReferenceToTypes _old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting {138 LinkReferenceToTypes _old( const Indexer *indexer );132 struct LinkReferenceToTypes final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes>, public WithShortCircuiting { 133 LinkReferenceToTypes( const Indexer *indexer ); 139 134 void postvisit( TypeInstType *typeInst ); 140 135 … … 170 165 171 166 /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID. 172 struct ForallPointerDecay _oldfinal {167 struct ForallPointerDecay final { 173 168 void previsit( ObjectDecl * object ); 174 169 void previsit( FunctionDecl * func ); … … 295 290 296 291 void validate( std::list< Declaration * > &translationUnit, __attribute__((unused)) bool doDebug ) { 297 PassVisitor<EnumAndPointerDecay _old> epc;298 PassVisitor<LinkReferenceToTypes _old> lrt( nullptr );299 PassVisitor<ForallPointerDecay _old> fpd;292 PassVisitor<EnumAndPointerDecay> epc; 293 PassVisitor<LinkReferenceToTypes> lrt( nullptr ); 294 PassVisitor<ForallPointerDecay> fpd; 300 295 PassVisitor<CompoundLiteral> compoundliteral; 301 296 PassVisitor<ValidateGenericParameters> genericParams; … … 310 305 ReplaceTypedef::replaceTypedef( translationUnit ); 311 306 ReturnTypeFixer::fix( translationUnit ); // must happen before autogen 312 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes _oldbecause it is an indexer and needs correct types for mangling307 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes because it is an indexer and needs correct types for mangling 313 308 } 314 309 { … … 319 314 }); 320 315 Stats::Time::TimeBlock("Fix Qualified Types", [&]() { 321 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes _old, because aggregate members are accessed316 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes, because aggregate members are accessed 322 317 }); 323 318 Stats::Time::TimeBlock("Hoist Structs", [&]() { … … 331 326 Stats::Heap::newPass("validate-C"); 332 327 Stats::Time::BlockGuard guard("validate-C"); 333 acceptAll( translationUnit, genericParams ); // check as early as possible - can't happen before LinkReferenceToTypes _old328 acceptAll( translationUnit, genericParams ); // check as early as possible - can't happen before LinkReferenceToTypes 334 329 VerifyCtorDtorAssign::verify( translationUnit ); // must happen before autogen, because autogen examines existing ctor/dtors 335 330 ReturnChecker::checkFunctionReturns( translationUnit ); … … 349 344 }); 350 345 Stats::Time::TimeBlock("Generate Autogen routines", [&]() { 351 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay _old346 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay 352 347 }); 353 348 } … … 390 385 391 386 void validateType( Type *type, const Indexer *indexer ) { 392 PassVisitor<EnumAndPointerDecay _old> epc;393 PassVisitor<LinkReferenceToTypes _old> lrt( indexer );394 PassVisitor<ForallPointerDecay _old> fpd;387 PassVisitor<EnumAndPointerDecay> epc; 388 PassVisitor<LinkReferenceToTypes> lrt( indexer ); 389 PassVisitor<ForallPointerDecay> fpd; 395 390 type->accept( epc ); 396 391 type->accept( lrt ); … … 591 586 } 592 587 593 void EnumAndPointerDecay _old::previsit( EnumDecl *enumDecl ) {588 void EnumAndPointerDecay::previsit( EnumDecl *enumDecl ) { 594 589 // Set the type of each member of the enumeration to be EnumConstant 595 590 for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) { … … 623 618 } 624 619 625 void EnumAndPointerDecay _old::previsit( FunctionType *func ) {620 void EnumAndPointerDecay::previsit( FunctionType *func ) { 626 621 // Fix up parameters and return types 627 622 fixFunctionList( func->parameters, func->isVarArgs, func ); … … 629 624 } 630 625 631 LinkReferenceToTypes _old::LinkReferenceToTypes_old( const Indexer *other_indexer ) {626 LinkReferenceToTypes::LinkReferenceToTypes( const Indexer *other_indexer ) { 632 627 if ( other_indexer ) { 633 628 local_indexer = other_indexer; … … 637 632 } 638 633 639 void LinkReferenceToTypes _old::postvisit( EnumInstType *enumInst ) {634 void LinkReferenceToTypes::postvisit( EnumInstType *enumInst ) { 640 635 EnumDecl *st = local_indexer->lookupEnum( enumInst->name ); 641 636 // it's not a semantic error if the enum is not found, just an implicit forward declaration … … 657 652 } 658 653 659 void LinkReferenceToTypes _old::postvisit( StructInstType *structInst ) {654 void LinkReferenceToTypes::postvisit( StructInstType *structInst ) { 660 655 StructDecl *st = local_indexer->lookupStruct( structInst->name ); 661 656 // it's not a semantic error if the struct is not found, just an implicit forward declaration … … 670 665 } 671 666 672 void LinkReferenceToTypes _old::postvisit( UnionInstType *unionInst ) {667 void LinkReferenceToTypes::postvisit( UnionInstType *unionInst ) { 673 668 UnionDecl *un = local_indexer->lookupUnion( unionInst->name ); 674 669 // it's not a semantic error if the union is not found, just an implicit forward declaration … … 683 678 } 684 679 685 void LinkReferenceToTypes _old::previsit( QualifiedType * ) {680 void LinkReferenceToTypes::previsit( QualifiedType * ) { 686 681 visit_children = false; 687 682 } 688 683 689 void LinkReferenceToTypes _old::postvisit( QualifiedType * qualType ) {684 void LinkReferenceToTypes::postvisit( QualifiedType * qualType ) { 690 685 // linking only makes sense for the 'oldest ancestor' of the qualified type 691 686 qualType->parent->accept( *visitor ); … … 734 729 } 735 730 736 void LinkReferenceToTypes _old::postvisit( TraitDecl * traitDecl ) {731 void LinkReferenceToTypes::postvisit( TraitDecl * traitDecl ) { 737 732 if ( traitDecl->name == "sized" ) { 738 733 // "sized" is a special trait - flick the sized status on for the type variable … … 756 751 } 757 752 758 void LinkReferenceToTypes _old::postvisit( TraitInstType * traitInst ) {753 void LinkReferenceToTypes::postvisit( TraitInstType * traitInst ) { 759 754 // handle other traits 760 755 TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name ); … … 782 777 } 783 778 784 void LinkReferenceToTypes _old::postvisit( EnumDecl *enumDecl ) {779 void LinkReferenceToTypes::postvisit( EnumDecl *enumDecl ) { 785 780 // visit enum members first so that the types of self-referencing members are updated properly 786 781 if ( enumDecl->body ) { … … 804 799 } 805 800 806 void LinkReferenceToTypes _old::renameGenericParams( std::list< TypeDecl * > & params ) {801 void LinkReferenceToTypes::renameGenericParams( std::list< TypeDecl * > & params ) { 807 802 // rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g. 808 803 // forall(otype T) … … 822 817 } 823 818 824 void LinkReferenceToTypes _old::previsit( StructDecl * structDecl ) {819 void LinkReferenceToTypes::previsit( StructDecl * structDecl ) { 825 820 renameGenericParams( structDecl->parameters ); 826 821 } 827 822 828 void LinkReferenceToTypes _old::previsit( UnionDecl * unionDecl ) {823 void LinkReferenceToTypes::previsit( UnionDecl * unionDecl ) { 829 824 renameGenericParams( unionDecl->parameters ); 830 825 } 831 826 832 void LinkReferenceToTypes _old::postvisit( StructDecl *structDecl ) {827 void LinkReferenceToTypes::postvisit( StructDecl *structDecl ) { 833 828 // visit struct members first so that the types of self-referencing members are updated properly 834 829 // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults) … … 844 839 } 845 840 846 void LinkReferenceToTypes _old::postvisit( UnionDecl *unionDecl ) {841 void LinkReferenceToTypes::postvisit( UnionDecl *unionDecl ) { 847 842 if ( unionDecl->body ) { 848 843 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name ); … … 856 851 } 857 852 858 void LinkReferenceToTypes _old::postvisit( TypeInstType *typeInst ) {853 void LinkReferenceToTypes::postvisit( TypeInstType *typeInst ) { 859 854 // ensure generic parameter instances are renamed like the base type 860 855 if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name; … … 893 888 } 894 889 895 void ForallPointerDecay _old::previsit( ObjectDecl *object ) {890 void ForallPointerDecay::previsit( ObjectDecl *object ) { 896 891 // ensure that operator names only apply to functions or function pointers 897 892 if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) { … … 901 896 } 902 897 903 void ForallPointerDecay _old::previsit( FunctionDecl *func ) {898 void ForallPointerDecay::previsit( FunctionDecl *func ) { 904 899 func->fixUniqueId(); 905 900 } 906 901 907 void ForallPointerDecay _old::previsit( FunctionType * ftype ) {902 void ForallPointerDecay::previsit( FunctionType * ftype ) { 908 903 forallFixer( ftype->forall, ftype ); 909 904 } 910 905 911 void ForallPointerDecay _old::previsit( StructDecl * aggrDecl ) {906 void ForallPointerDecay::previsit( StructDecl * aggrDecl ) { 912 907 forallFixer( aggrDecl->parameters, aggrDecl ); 913 908 } 914 909 915 void ForallPointerDecay _old::previsit( UnionDecl * aggrDecl ) {910 void ForallPointerDecay::previsit( UnionDecl * aggrDecl ) { 916 911 forallFixer( aggrDecl->parameters, aggrDecl ); 917 912 } … … 1373 1368 } 1374 1369 1375 namespace { 1376 /// Replaces enum types by int, and function/array types in function parameter and return 1377 /// lists by appropriate pointers 1378 struct EnumAndPointerDecay_new { 1379 const ast::EnumDecl * previsit( const ast::EnumDecl * enumDecl ) { 1380 // set the type of each member of the enumeration to be EnumConstant 1381 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1382 // build new version of object with EnumConstant 1383 ast::ptr< ast::ObjectDecl > obj = 1384 enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1385 obj.get_and_mutate()->type = 1386 new ast::EnumInstType{ enumDecl->name, ast::CV::Const }; 1387 1388 // set into decl 1389 ast::EnumDecl * mut = mutate( enumDecl ); 1390 mut->members[i] = obj.get(); 1391 enumDecl = mut; 1392 } 1393 return enumDecl; 1394 } 1395 1396 static const ast::FunctionType * fixFunctionList( 1397 const ast::FunctionType * func, 1398 std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field, 1399 ast::ArgumentFlag isVarArgs = ast::FixedArgs 1400 ) { 1401 const auto & dwts = func->*field; 1402 unsigned nvals = dwts.size(); 1403 bool hasVoid = false; 1404 for ( unsigned i = 0; i < nvals; ++i ) { 1405 func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) ); 1406 } 1407 1408 // the only case in which "void" is valid is where it is the only one in the list 1409 if ( hasVoid && ( nvals > 1 || isVarArgs ) ) { 1410 SemanticError( 1411 dwts.front()->location, func, "invalid type void in function type" ); 1412 } 1413 1414 // one void is the only thing in the list, remove it 1415 if ( hasVoid ) { 1416 func = ast::mutate_field( 1417 func, field, std::vector< ast::ptr< ast::DeclWithType > >{} ); 1418 } 1419 1420 return func; 1421 } 1422 1423 const ast::FunctionType * previsit( const ast::FunctionType * func ) { 1424 func = fixFunctionList( func, &ast::FunctionType::params, func->isVarArgs ); 1425 return fixFunctionList( func, &ast::FunctionType::returns ); 1426 } 1427 }; 1428 1429 /// Associates forward declarations of aggregates with their definitions 1430 struct LinkReferenceToTypes_new final 1431 : public ast::WithSymbolTable, public ast::WithGuards, public 1432 ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting { 1433 1434 const ast::SymbolTable * localSyms; 1435 1436 LinkReferenceToTypes_new( const ast::SymbolTable & syms ) : localSyms( &syms ) {} 1437 1438 #warning incomplete 1439 }; 1440 1441 /// Replaces array and function types in forall lists by appropriate pointer type and assigns 1442 /// each object and function declaration a unique ID 1443 struct ForallPointerDecay_new { 1444 #warning incomplete 1445 }; 1446 } // anonymous namespace 1447 1448 const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab ) { 1449 ast::Pass< EnumAndPointerDecay_new > epc; 1450 ast::Pass< LinkReferenceToTypes_new > lrt{ symtab }; 1451 ast::Pass< ForallPointerDecay_new > fpd; 1452 1453 return type->accept( epc )->accept( lrt )->accept( fpd ); 1454 } 1455 1370 const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab ) { 1371 #warning unimplemented 1372 (void)type; (void)symtab; 1373 assert(false); 1374 return nullptr; 1375 } 1456 1376 } // namespace SymTab 1457 1377
Note:
See TracChangeset
for help on using the changeset viewer.